ViewPager使用中的一些问题与思考

来源:互联网 发布:gevent 数据库 编辑:程序博客网 时间:2024/05/17 06:47
  • 为什么使用ViewPager而不是RecyclerView

    使用RecyclerView的横向排列理论上也可以实现左右滑动,但有时候我们要展现的不是视图(View)对象,而是Fragment对象,而Fragment对象是由FragmentManager创建的,很明显RecyclerView的Adapter中没有持有FragmentManager对象,所以它的Adapter无法创建Fragment对象来展现给用户。相对应的,ViewPager的Adapter中就要求传入一个FragmentManager对象,也是因为这个原因。

  • 如何使用ViewPager

    ViewPager的Adapter实现起来要重写四个方法。由于ViewPager常常与Fragment连用,所以Google提供了两个专门用于Fragment的adapter。
    对于ViewPager和Fragment的联用,Google提供了两个专门的PagerAdapter:FragmentStatePagerAdapter和FragmentPagerAdapter。二者的区别在于前者会销毁不需要的Fragment并保存其中的临时数据,后者则不会销毁不需要的Fragment。对于多个页面选择前者,对于少数页面的显示选择后者更好。
    一个典型的代码如下

    vp_container.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {            @Override            public Fragment getItem(int position) {                Crime crime = crimeList.get(position);                return CrimeDetailFragment.newInstance(crime.getId());            }            @Override            public int getCount() {                return crimeList.size();            }            @Override            public int getItemPosition(Object object){                return PagerAdapter.POSITION_NONE;            }        });    UUID crimeId = (UUID) getIntent().getSerializableExtra("crimeId");    for (int i = 0; i<crimeList.size();i++){            if (crimeList.get(i).getId().equals(crimeId)){                vp_container.setCurrentItem(i);                break;            }        }

该方法会执行三次,生成三个Fragment,分别是中,左,右。当然也可以指定生成更多个,使用setOffscreenPageLimit()。

很蛋疼的是:

经过测试,如果仅仅完成setAdapter,ViewPager不会根据点击的item去加载模型类的对象,这是为什么呢?注意不要陷入一个误区:以上代码块并不是从上往下执行的!!!以上代码做了两件事,给ViewPager进行了setAdapter和setCurrentItem。不要想当然的以为setAdapter先执行了,而事实是,setCurrentItem先执行了!也就是说要先告诉ViewPager从那一行开始,然后它才去调用adapter给它装数据。如果不指定currentItem的话,默认从第一行开始显示。
以上代码块关键部分的正确执行顺序是:setCurrentItem–setAdapter–return CrimeFragment
经过测试,当adapter写成匿名类时程序可以运行,但是无法debug,我靠,什么鬼?

ViewPager删除page时临时数据的保存问题(巨坑)

比如List中有12345个数据,点击2,会依次创建213Fragment,删除2,依次销毁123Fragment,同时依次创建314Fragment,并且页面调到3.但是,如果213中有临时数据被托管Fragment的Activity自动保存下来的话,恢复时会出现问题:213的数据会分别恢复到314上面。比如2中有个EditText,其中的数据就会被保存下来,然后恢复时就会出现这种问题。

参考:http://www.jianshu.com/p/58579627f70a

解决办法就是强制不保存指定View的临时数据,即调用View的setSaveEnable()方法传入false。不保存临时数据,那数据怎么办呢?其实在Fragment被销毁的时候将数据提交就行了。这样也是一种保存的方法。

至于Fragment的数据为什么会被Activity保存,其实很好理解,Fragment是会被销毁的,如果数据由Fragment来保存,等于没保存。那Activity的数据由谁来保存呢?

0 0
原创粉丝点击