简体   繁体   中英

destroyItem being called when position ==2 why? android pagerAdapter

I have a very simple PagerAdapter that for some reason, removes the views at position 0 and 1 when it is scrolled to position 2.

Specifically, when I first run the app, there are 3 views. I scroll to position 2 and position 1's view will disappear. View 0 is still there. If I scroll to view 0 and back to view 2 and again back to view 0, View 0 suddenly disappears. I do the same again, and I can actually see view 0 being instantiated and immediately destroyed.

what is going on here?

Main Activity

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

您必须维护内存中的所有选项卡,将OffscreenPageLimit指定为N-1,在您的情况下,请将其放在onCreate方法中:

myPager.setOffscreenPageLimit(2);

Checkout populate() function from ViewPager source - it has clear checks then to remove currentIndex+1 and currentIndex-1 items. Removing is done based on view sizes and it seems to be entirely internal ViewPager logic. ViewPager source is located

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

.

You might debug ViewPager to know that is happening exactly, but I wouldn't suggest so until You faced some serious issue with ViewPager. What's why: if you dig into ViewPager code it might lead You to write some hackish code (even not intentionally) on it based on its internal structure and not on its public interface and documentation. So, the main idea of data encapsulation would be ruined which is definitely not good (sadly, sometimes we need to do so in Android due to lack of documentation / unclear naming / android internal issues etc., check Code Complete by Steve McConnell for more details on good encapsulation etc.).

Here the key is that position is different then index. If they give you a position there is no guarantee that your collections haven't removed other positions.

Example: Let's say your at position 2. destroyItem might have been called for position 0 which means in your collections now position 2 is actually at index 1. So your indexes will quickly become out of sync from your positions. The same thing happens with listview children. I would recommend using a sparseArray instead.

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);
     }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM