前言

在项目中,我采用的是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的刷新。

更多相关文章

  1. Android(安卓)多线程之IntentService 完全详解
  2. Android获取LayoutInflater对象的方法总结
  3. Android(安卓)ActionBar完全解析上
  4. Android中事件分发机制详解
  5. Android自定义Dialog二次调用报错解决方法:The specified child a
  6. Rxjava的基础用法和源码解析(一)
  7. Android(安卓)Junit Test
  8. Android(安卓)JsBridge源码学习
  9. Android(安卓)刷新页面更新数据方法探究

随机推荐

  1. 自定义Dialog 去掉标题
  2. Android中实现为TextView添加多个可点击
  3. Android应用程序签名和权限增强应用程序
  4. 【Shader】适合 Android(安卓)手机上 Gra
  5. [android]一个关于UDP和TCP的项目实践(二
  6. Android(安卓)推送之原理与初触Androidpn
  7. [原] Android中怎么将图片平铺
  8. 摘要:HenCoder Android(安卓)自定义 View
  9. 如何把React Native嵌入到原生android应
  10. Android新技术------Android(安卓)App Bu