Android中解决FragmentPagerAdapter刷新Fragment无效的问题
16lz
2021-01-26
前言
在项目中,我采用的是ViewPager+FragmentPagerAdapter+Fragment的方式,要实现fragment的刷新,但是发现并没有把ViewPager中的fragment替换掉,因此上网查阅了很多博客,最后解决了这个问题。
解决方法
我就直接贴上我的代码
public class MyViewPagerAdapter extends FragmentPagerAdapter { private List mFragments = new ArrayList<>(); public MyViewPagerAdapter(@NonNull FragmentManager fm, List mFragments) { super(fm); this.mFragments = mFragments; } @NonNull @Override public Fragment getItem(int position) { return mFragments.get(position); } @Override public int getCount() { return mFragments.size(); } //原本ViewPager内存中缓存了Fragment,重写该方法使adapter重新创建新的Fragment @Override public long getItemId(int position) { return mFragments.get(position).hashCode(); } @Override public int getItemPosition(Object object) { return POSITION_NONE; }}
主要是重写两个方法
@Override public int getItemPosition(Object object) { return POSITION_NONE; }
设置POSITION_NONE的目的是可以执行instantiateItem,刷新Fragment就需要这行该函数。
instantiateItem方法源码如下:
@Overridepublic Object instantiateItem(ViewGroup container, int position) {if (mCurTransaction == null) {mCurTransaction = mFragmentManager.beginTransaction();}final long itemId = getItemId(position);// Do we already have this fragment?String name = makeFragmentName(container.getId(), itemId);Fragment fragment = mFragmentManager.findFragmentByTag(name);if (fragment != null) {if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);mCurTransaction.attach(fragment);} else {fragment = getItem(position);if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);mCurTransaction.add(container.getId(), fragment,makeFragmentName(container.getId(), itemId));}if (fragment != mCurrentPrimaryItem) {fragment.setMenuVisibility(false);fragment.setUserVisibleHint(false);}return fragment;}
我们发现每次创建fragment时候,FragmentManager都会通过findFragmentByTag去缓存中查找,是否存在指定tagName的Fragment,有就复用,没有就创建新的Fragment,而这里的tagName就是通过getItemId()方法生成的。
因此FragmentPagerAdapter是根据getItemId(int position)来判断当前position的Fragment是否存在的。
而getItemId的源码是:
public long getItemId(int position) { return position; }
这样的话getItemId返回的值并不唯一,会导致获取到的Fragment是旧的Fragment。
因此我们需要让getItemId返回一个唯一的值,因此重写该方法如下:
@Overridepublic long getItemId(int position) {return mFragments.get(position).hashCode();}
之后调用pagerAdapter的notifyDataSetChanged方法就可以实现Fragment的刷新。
更多相关文章
- Android(安卓)多线程之IntentService 完全详解
- Android获取LayoutInflater对象的方法总结
- Android(安卓)ActionBar完全解析上
- Android中事件分发机制详解
- Android自定义Dialog二次调用报错解决方法:The specified child a
- Rxjava的基础用法和源码解析(一)
- Android(安卓)Junit Test
- Android(安卓)JsBridge源码学习
- Android(安卓)刷新页面更新数据方法探究