ViewrAdapter中的instantiateItem(ViewGroup,int)和ViewPager中的AddView混淆

时间:2011-09-01 23:48:12

标签: android layout android-viewpager

到目前为止,我一直在黑客攻击示例,以便了解Android SDK作为一个整体的API。但是,我陷入了僵局。

我正在尝试使用XML文件中的2个TextView来为LinearLayout充气。这些将是分页的视图。我根本无法让这个工作,并意识到我完全不明白代码发生了什么。

查看源代码我可以看到方法ViewPager.addNewItem从提供的适配器调用InstantiateItem。并在populate()中调用addNewItem。 populate()在许多其他地方被调用。

无论如何,在这个例子中,我经历过,当为PagerAdapter覆盖该方法时,必须在ViewPager集合上包含对addView()的调用,该集合作为参数从ViewPager传递。

如果我想添加多个视图,我认为这将是多次调用addView()的情况,但是当instantiateItem()将一个Object返回给ViewPager时(在示例中我让它返回它添加的视图)I不知道该返回什么。我已经尝试返回膨胀的视图和其他一些东西。

拜托,有人可以解释这里发生了什么吗?

非常感谢。

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

    layout = inflater.inflate(R.layout.animallayout, null);
    TextView tv = (TextView) layout.findViewById(R.id.textView1);
    tv.setText("1________________>" + position);

    TextView tv2 = (TextView) layout.findViewById(R.id.textView2);
    tv.setText("2________________>" + position);

    ((ViewPager) collection).addView(layout);
    return layout;
}

2 个答案:

答案 0 :(得分:57)

我最近实现了这个,这是我的instantiateItem方法(因为它的可读性有点小。

@Override
public Object instantiateItem(View collection, int position) {
    Evaluation evaluation = evaluations.get(position);

    View layout = inflater.inflate(R.layout.layout_evaluation, null);

    TextView evaluationSummary = (TextView) layout.findViewById(R.id.evaluation_summary);
    evaluationSummary.setText(evaluation.getEvaluationSummary());

    ((ViewPager) collection).addView(layout);

    return layout;
}

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

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

因此,对于显示的页面,我使用位置作为索引从evaluations列表中获取数据。 然后膨胀Layout,其中包含我将添加数据的视图。 然后我得到TextView来设置评估摘要文本。 然后整个Layout被添加到ViewPager。 最后还返回Layout

如果你仍然无法发布你的代码。

答案 1 :(得分:15)

我对这个适配器的工作原理有同样的误解,我已经做了一些调查 关键的特点是您的观点存储在两个地方:
在ViewPager中,您可以通过调用((ViewPager) container).addView(view);添加它们(此处您只需存储三个视图,您可以看到的内容以及左右邻域)
private final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>();中的{2}这是ViewPager的成员,存储的视图包含有关它们的信息(通过调用适配器方法mAdapter.instantiateItem(this, position);添加它们)

static class ItemInfo {
    Object object;
    int position;
    boolean scrolling;
    float widthFactor;
    float offset;
}

当幻灯片ViewPagermItems数组获取视图位置或实例化它时,并将此视图与ViewPager的子项与适配器方法public boolean isViewFromObject(View view, Object object)进行比较。在object上向用户显示等于ViewPager的视图。如果没有视图,则显示空白屏幕 这是ViewPager方法,其中视图与对象进行比较:

ItemInfo infoForChild(View child) {
    for (int i=0; i<mItems.size(); i++) {
        ItemInfo ii = mItems.get(i);
        if (mAdapter.isViewFromObject(child, ii.object)) {
            return ii;
        }
    }
    return null;
}

如果来自mItems的视图位置不在范围{currentposition -1,currentposition +1}中,那么它将被销毁:

mItems.remove(itemIndex);
mAdapter.destroyItem(this, pos, ii.object);

ViewPagers内存1

的视图

向前滑动时,destroyItemdestroyItem的一个陷阱称为IllegalStateException: The specified child already has a parent.,然后添加新项目,但是当您向后滑动时,首先添加新项目,然后销毁旧项目。如果您尝试仅使用三个缓存视图,则可以在向后滑动时获得{{1}}。

ViewPager memory