23

到目前为止,我一直在拼凑一些示例,以了解整个 Android SDK 的 API。然而,我陷入了僵局。

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

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

无论如何,在示例中,我已经体验到,当为 PagerAdapter 重写该方法时,必须包含对从作为参数addView()传递的 ViewPager 集合的调用。ViewPager

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

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

非常感激。

@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;
}
4

2 回答 2

58

我最近实现了这个,这是我的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也返回了。

如果您仍然无法获得它,请发布您的代码。

于 2011-09-02T00:48:53.690 回答
17

我对这个适配器的工作方式有同样的误解,我已经做了一些调查。
关键的特殊性是您的视图存储在两个地方:
1 在 ViewPager 中您通过调用添加它们((ViewPager) container).addView(view);(这里您只需要存储三个视图,您所看到的以及左右邻域)
2private final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>();这是 ViewPager 中存储的成员带有位置信息的视图(通过调用适配器方法在此处添加它们mAdapter.instantiateItem(this, position);

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

当您ViewPager从数组中获取视图位置mItems或实例化它并将此视图与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的视图

这是一个陷阱,destroyItem当您向前滑动 fis 时会调用destroyItem然后添加新项目,但是当您先向后滑动时会添加新项目然后旧项目被销毁。如果您尝试仅使用三个缓存视图,则可以IllegalStateException: The specified child already has a parent.在向后滑动时获得。

ViewPager 内存

于 2013-05-27T11:31:57.480 回答