源码中FragmentPagerAdapter
在instantiateItem
时会先去通过tag
来找对应Fragment
如果存在就直接使用,如果不存在则通过makeFragmentName
生成tag
创建新的Fragment
public Object instantiateItem(ViewGroup container, int position) {
//..
//..
long itemId = this.getItemId(position);
String name = makeFragmentName(container.getId(), itemId);
if(fragment != null) {
this.mCurTransaction.attach(fragment);
} else {
fragment = this.getItem(position);
this.mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId));
}
//..
//..
}
private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
}
这样在某些情况下会带来一些问题,例如:
- 需要动态更新ViewPager某一个Item,但由于缓存造成无法正常更新。
- 当应用后台挂起被回收 或 使用 某些手机助手的清理功能时 再次打开应用,activity 被重建,但fragment 依旧在缓存中存在,造成fragment 中依旧控制着旧得activity的引用。
解决方法
- 每次重新进入时清空所有
fragment
缓存,或更具源码的tag
生成规则,清空对应缓存 - 可以直接copy
FragmentPagerAdapter
源码 来更具自己需求来制定规则 - 针对动态更新页面 也可以使用
FragmentStatePagerAdapter
- 因为
adapter
中tag
是根据container id
和getItemId
来成的,所以可以在重写getItemId
是根据需要来返回不同ID 来避开缓存