当position == 2为什么时会调用destroyItem? android pagerAdapter

时间:2012-09-22 01:31:09

标签: android

我有一个非常简单的PagerAdapter,由于某种原因,删除位置0和位置的视图 1当它滚动到位置2时。

具体来说,当我第一次运行应用程序时,有3个视图。我滚动到位置2,位置1的视图将消失。视图0仍然存在。如果我滚动到查看0并返回到视图2并再次返回查看0,则视图0突然消失。我再次这样做,我实际上可以看到视图0被实例化并立即被销毁。

这里发生了什么?

主要活动

public class MainActivity extends Activity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final MyPagerAdapter adapter = new MyPagerAdapter(this);
        final ViewPager myPager = (ViewPager) findViewById(R.id.mypanelpager);
        myPager.setAdapter(adapter);
        myPager.setCurrentItem(1);
}


public class MyPagerAdapter extends PagerAdapter {

private Context ctx;
Calendar c = Calendar.getInstance();
int month = c.get(Calendar.MONTH);
int year = c.get(Calendar.YEAR);
ViewGroup collection;

public MyPagerAdapter (Context ctx){
    this.ctx = ctx ;
}


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

public Object instantiateItem(ViewGroup container, int position ){
    this.collection = (ViewPager)container;
    NewMonth monthObject = new NewMonth(ctx, month+position-1,2012);
    View monthLayout = monthObject.newParentLayout;
    collection.addView(monthLayout);
    return monthLayout;
    return addViewAt(position);
    }


@Override
    public void destroyItem(ViewGroup container, int position, Object object) {
    collection.removeViewAt(position);
}


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


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

3 个答案:

答案 0 :(得分:4)

你必须维护内存中的所有标签,指定OffscreenPageLimit为N-1,在你的情况下将它放在onCreate方法中:

myPager.setOffscreenPageLimit(2);

答案 1 :(得分:1)

populate()来源检出ViewPager函数 - 它有明确的检查,然后删除currentIndex + 1和currentIndex-1项。删除是基于视图大小完成的,它似乎完全是内部ViewPager逻辑。 ViewPager源位于

<android sdk folder>\extras\android\support\v4\src\java\android\support\v4\view\ViewPager.jav‌​a

您可能会调试ViewPager以确切知道这种情况正在发生,但在您遇到ViewPager严重问题之前我不会这么做。原因是:如果你深入研究ViewPager代码,它可能会导致你根据内部结构而不是公共接口和文档编写一些hackish代码(甚至不是故意的)。因此,数据封装的主要思想将被破坏,这绝对不好(遗憾的是,有时我们需要在Android中这样做,因为缺乏文档/不清楚命名/ android内部问题等,请查看Code Complete by Steve McConnell了解更多信息有关良好封装等的详细信息。)。

答案 2 :(得分:0)

这里的关键是位置与索引不同。如果他们给您一个位置,则无法保证您的收藏品无法移除其他位置。

实施例: 让我们说你的位置2. destroyItem可能已经调用了位置0,这意味着在你的集合中,位置2实际上是在索引1.所以你的索引很快就会从你的位置变得不同步。 listview孩子也会发生同样的事情。我建议改用sparseArray。

private final SparseArray<View> views = new SparseArray<>();

public View instantiateItem(ViewGroup container, final int position) {
    ...
    views.put(position, view);
    ...
}

public void destroyItem(ViewGroup container, int position, Object object) {
     View view = views.get(position);
     if (view != null) {
         container.removeView(view);
         views.remove(position);
     }
}