如何从视图翻页器中访问视图

12

我在我的活动中使用了视图分页器。我为7个页面创建了视图。现在我想在我的活动中访问页面视图。但我得到的数据为空白。

在活动中
public class ActivitySingleEntry extends Activity implements OnClickListener {

    private ViewPager mPager;
    private FixedTabsView mFixedTabs;

    private ExamplePagerAdapter mPagerAdapter;
    private TabsAdapter mFixedTabsAdapter;
    private EditText edtFieldName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_fixed_tabs);
        initViewPager(7, 0xFFFFFFFF, 0xFF000000);
        mFixedTabs = (FixedTabsView) findViewById(R.id.fixed_tabs);
        mFixedTabsAdapter = new FixedTabsAdapter(this);
        mFixedTabs.setAdapter(mFixedTabsAdapter);
        mFixedTabs.setViewPager(mPager);

    }

    private void initViewPager(int pageCount, int backgroundColor, int textColor) {
        mPager = (ViewPager) findViewById(R.id.pager);
        mPagerAdapter = new ExamplePagerAdapter(this, pageCount,
                backgroundColor, textColor);
        mPager.setAdapter(mPagerAdapter);
        mPager.setCurrentItem(1);
        mPager.setPageMargin(5);
    }

    @Override
    public void onClick(View v) {

//      LinearLayout lin=(LinearLayout) mPager.getChildAt(mPager.getCurrentItem());
//      edtFieldName=(EditText) lin.findViewById(R.id.edtFieldName);
//      Log.d("test", "From get child:"+edtFieldName.getText().toString()+":");

        Log.d("test", "Current Page:"+mPager.getCurrentItem());

        LinearLayout linearLayout=(LinearLayout) mPager.findViewWithTag("lin"+mPager.getCurrentItem());
        edtFieldName=(EditText) linearLayout.findViewById(R.id.edtFieldName);

        edtFieldName=(EditText) findViewById(R.id.edtFieldName);
        if (edtFieldName==null) {
            ShowToast.makeToast(getApplicationContext(), "Edt null");
        }else
        ShowToast.makeToast(getApplicationContext(),
                "Data saved " + edtFieldName.getText().toString() + ":"
                        + mPager.getCurrentItem());
    }
}

我的页面适配器

public class ExamplePagerAdapter extends PagerAdapter {

    protected transient Activity mContext;

    private int mLength = 0;
    private int mBackgroundColor = 0xFFFFFFFF;
    private int mTextColor = 0xFF000000;

    private String[] mData = { "Temperature", "Sugar", "BP", "Field 4",
            "Field 5", "Field 6", "Field 7" };

    public ExamplePagerAdapter(Activity context, int length,
            int backgroundColor, int textColor) {

        mContext = context;
        mLength = length;
        mBackgroundColor = backgroundColor;
        mTextColor = textColor;

    }

    @Override
    public int getCount() {
        return mLength;
    }

    @Override
    public Object instantiateItem(View container, int position) {

        LinearLayout linearLayout = (LinearLayout) View.inflate(mContext,
                R.layout.activity_single_entry, null);

        TextView txtFieldName = (TextView) linearLayout
                .findViewById(R.id.txtFieldName);
        EditText edtFieldName = (EditText) linearLayout
                .findViewById(R.id.edtFieldName);

        String filedName = mData[position];
        txtFieldName.setText(filedName);
        edtFieldName.setHint("Please enter " + filedName);
        edtFieldName.setInputType(InputType.TYPE_CLASS_TEXT);

        if (filedName.equals("Temperature")) {
            edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
        } else if (filedName.equals("Sugar")) {
            edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
        } else if (filedName.equals("BP")) {
            edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
        }


        edtFieldName.setTag("edt");

        ((ViewPager) container).addView(linearLayout, 0);
        linearLayout.setTag("lin"+position);

        Log.d("test", "Adapter creating item:"+position );
        return linearLayout;
    }



    @Override
    public void destroyItem(View container, int position, Object view) {
        ((ViewPager) container).removeView((View) view);
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == ((View) object);
    }

    @Override
    public void finishUpdate(View container) {
    }

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void startUpdate(View container) {
    }

}

在R.layout.activity_single_entry.xml中,我有一个带有onclick的EditText和Button。

我的Xml

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/txtFieldName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView" />

        <EditText
            android:id="@+id/edtFieldName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_weight="1"
            android:hint="Please enter field value" />
    </LinearLayout>

    <Button
        android:id="@+id/btnSave"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Save" 
        android:layout_margin="20dp"
        android:onClick="onClick"
        />

</LinearLayout>
如果我在内部使用PageAdapter。
@Override
    public int getItemPosition(Object object) {
        // TODO Auto-generated method stub
        return POSITION_NONE;
    }

我能够获得第一页的值,但不是全部页面。


你遇到了什么错误?我发现在这一行代码中 LinearLayout linearLayout=(LinearLayout) mPager.findViewWithTag("lin"+mPager.getCurrentItem()+1); 返回了 null。 - flexdroid
有时会抛出空指针异常。如果我尝试使用getChildAt(pos),则会抛出IllegalStateException。 - Swapnil Deshmukh
你有没有考虑从getItemPosition()方法中返回真实值? - meh
将代码中的 +1LinearLayout linearLayout=(LinearLayout) mPager.findViewWithTag("lin"+mPager.getCurrentItem()+1); 中删除,使其变为 LinearLayout linearLayout=(LinearLayout) mPager.findViewWithTag("lin"+mPager.getCurrentItem());。在调试时,我发现 mPager.getCurrentItem()+1 返回了11。 - flexdroid
已删除它。但是仍然更新了帖子 :( 噢 - Swapnil Deshmukh
3个回答

13

首先,您需要使用setTag()方法:

linearLayout.setTag("lin"+position);

位置位于<0..numPages-1>

但请仔细阅读:

LinearLayout linearLayout=(LinearLayout) mPager.findViewWithTag("lin"+mPager.getCurrentItem());

findViewWithTag是在所有页面上都返回null,还是只有在最后一页上返回null?如果是第一页,则mPager.getCurrentItem()会返回0,因此在读取时不需要添加+1。


好的,我明白了。由于当ii == 2时,“lin”+ ii + 1表达式等于“lin21”,而不是人们可能想象的“lin3”,所以你到处都有null。 - pskink
是的,我明白了,我编辑了我的帖子,谢谢。但仍然无法获取数据。 - Swapnil Deshmukh
删除以下代码行:edtFieldName = (EditText) findViewById(R.id.edtFieldName); - pskink
@pskink 标签,简单而强大。谢谢你提醒我这一点。 - Lev
谢谢,整天都在寻找这个解决方案。 - Naveen Kumar M

1

在页面适配器中,我在每一页都使用单个视图,因此它仅引用第一个项目。如果我尝试获取页面的视图,它只会给我第一个对象,因此我为每个页面的编辑文本应用了不同的ID。

在页面适配器中

@Override
public Object  instantiateItem(View container, int position) {

    LinearLayout linearLayout = (LinearLayout) View.inflate(mContext,
            R.layout.activity_single_entry, null);

    TextView txtFieldName = (TextView) linearLayout
            .findViewById(R.id.txtFieldName);
    EditText edtFieldName = (EditText) linearLayout
            .findViewById(R.id.edtFieldName);
    ***edtFieldName.setId(position);***

    String filedName = mData[position];
    txtFieldName.setText(filedName);
    edtFieldName.setHint("Please enter " + filedName);
    edtFieldName.setInputType(InputType.TYPE_CLASS_TEXT);

    if (filedName.equals("Temperature")) {
        edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
    } else if (filedName.equals("Sugar")) {
        edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
    } else if (filedName.equals("BP")) {
        edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
    }


    edtFieldName.setTag("edt"+position);

    ((ViewPager) container).addView(linearLayout, 0);
    mItems.add(linearLayout);

    linearLayout.setTag("lin"+position);

    Log.d("test", "Adapter creating item:"+position );
    return linearLayout;
}

它现在正在工作


-1
一个快速的解决方案是在ExamplePagerAdapter中保持一个List,并在addView()调用后添加到它。然后,您可以实现一个公共函数,例如getItemAtPosition(int position),它返回ViewPager页面上的LinearLayout。然后,您可以在Activity中对该线性布局运行findViewById(R.id.edtFieldName)。代码如下:
在您的ExamplePagerAdapter中,添加一个私有对象:
List<LinearLayout> mItems;

在你的构造函数中添加:
mItems = new Vector<LinearLayout>();

在 instantiateItem() 中添加:
((ViewPager) container).addView(linearLayout, 0);
mItems.add(linearLayout);

然后添加一个方法:

public LinearLayout getItemAtPosition(int position) {
    return mItems.get(position);
}

然后在您的Activity中使用该方法。希望这就是您要寻找的。


谢谢回复。之前我尝试过,但是获取到的数据仍然为空。 - Swapnil Deshmukh
不用担心。另一个可能有效的选项是在您的活动中使用getChildAt()来获取ViewPager(mPager)上的LinearLayout。我不确定那是否有效,但值得一试。 - Meehow
不是同一个问题。如果你看到代码,我会注释掉那段代码,但问题仍然存在。有时它会触发异常。 - Swapnil Deshmukh
1
这里还有另一种方法。在您的Activity的onClick()方法中,您可以调用被点击的按钮的getParent()方法,即v.getParent()。那应该是您要找的LinearLayout - 只要您拥有正确的LinearLayout,就可以对其进行findViewById()操作以获取EditText。 - Meehow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接