谈谈FragmentPagerAdapter和FragmentStatePagerAdapter
来源:互联网 发布:原生js请求接口 编辑:程序博客网 时间:2024/06/04 17:52
两者区别
这两个类都是继承自PagerAdapter,只是他们的处理的方式不一样。(代码我就不贴了,大家可自行在AS上看源码)
首先是FragmentPagerAdapter,他是将已经生成的Fragment都保存下来,切换页面时如果Fragment不存在就先生成一个,如果已经存在了就直接attach这个fragment,旧Fragment只被detach掉,但不会将其移除。
然后是FragmentStatePagerAdapter,他是按需生成Fragment,根据用户设定的保存页面数量来缓存Fragment,超过的将会被移除。
使用场景
看了上面所说的两者区别,相信大家心里都比较清楚了,FragmentPagerAdapter适合使用在数量少的情况下,如首页固定的几个Fragment(如微信首页的微信,通讯录,发我,我)。FragmentStatePagerAdapter适合使用在数量多或不确定的情况下(如今日头条的新闻分类,科技,娱乐,生活等)
碰到的问题
有时可能有同学会问,使用了FragmentPagerAdapter有时会报错
java.lang.IllegalStateException: Can’t change tag of fragment PageFragment
这个问题可以追溯到FragmentPagerAdapter的缓存机制,由于他是缓存所有页面,所以每个页面都有一个唯一id对应,这个id是由方法getItemId生成
/** * Return a unique identifier for the item at the given position. * * <p>The default implementation returns the given position. * Subclasses should override this method if the positions of items can change.</p> * * @param position Position within this adapter * @return Unique identifier for the item at position */ public long getItemId(int position) { return position; }
默认就是用position作为id,如果同时存在多个id相同fragment就会报错,具体代码如下
private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) { //=======省略代码====== if (tag != null) { if (fragment.mTag != null && !tag.equals(fragment.mTag)) { throw new IllegalStateException("Can't change tag of fragment " + fragment + ": was " + fragment.mTag + " now " + tag); } fragment.mTag = tag; } //=======省略代码======= }
什么情况下会出现这种情况?
一般我们用FragmentPagerAdapter不会重写getItemId方法,所以唯一id就是position,当adapter里的数据发生改变(即fragment数量改变了或fragment有被替换的情况),由于旧id的fragment被缓存,这就导致id一样但fragment对象不一样的情况。
怎么解决?
网上很多都说重写getItemId方法,自己生成一个唯一id(如fragment的hashcode等)来处理,这个方法看上去可行,但忽略了一种特殊情况,就是被系统回收后进行恢复的情况,恢复是会重新生成fragment的,此时由于使用hashcode,所以两个id就不一样了导致报错,除非你能设计出一个恢复的时候也是相同id的算法,否则不要使用此方法。
开头我说过FragmentPagerAdapter的使用场景,既然需求是可变的fragment列表,那为什么还要使用FragmentPagerAdapter来实现呢?所以这里只要换成FragmentStatePagerAdapter来实现即可。
- 谈谈FragmentPagerAdapter和FragmentStatePagerAdapter
- FragmentPagerAdapter 和FragmentStatePagerAdapter
- viewpager : FragmentStatePagerAdapter和FragmentPagerAdapter
- FragmentPagerAdapter 和 FragmentStatePagerAdapter 区别
- FragmentStatePagerAdapter和FragmentPagerAdapter
- FragmentPagerAdapter 和 FragmentStatePagerAdapter比较
- FragmentStatePagerAdapter和FragmentPagerAdapter
- FragmentStatePagerAdapter和FragmentPagerAdapter
- FragmentStatePagerAdapter 和 FragmentPagerAdapter 对比
- FragmentPagerAdapter和FragmentStatePagerAdapter的区别
- PagerAdapter、FragmentPagerAdapter和FragmentStatePagerAdapter描述
- FragmentPagerAdapter和FragmentStatePagerAdapter的区别
- FragmentPagerAdapter和FragmentStatePagerAdapter的区别
- FragmentPagerAdapter和FragmentStatePagerAdapter的区别
- FragmentPagerAdapter和FragmentStatePagerAdapter的区别
- FragmentpagerAdapter和FragmentStatePagerAdapter的区别
- 【Android基础知识】FragmentPagerAdapter和FragmentStatePagerAdapter
- FragmentPagerAdapter和FragmentStatePagerAdapter的区别
- py 基本信息输入框 笔记
- 练习 10:Bash:程序退出代码(返回状态)
- Spring个人总结3
- bootstrap selectpicker控件select下拉框动态数据无法回显的问题 && 不可编辑的下拉框数据提交至后台
- Road (拓扑序dp)
- 谈谈FragmentPagerAdapter和FragmentStatePagerAdapter
- 生产者消费者模式 锁优化
- bootstrap水平表单
- 信息安全基础知识总结一
- Tomcat-JDBC源码解析及优化
- unity的垂直同步VSync
- 结构体转为char数组 & char数组转为结构体
- mysql查询表的相关信息
- chess (状压dp)