Android中解决FragmentPagerAdapter刷新Fragment无效的问题

前言

在项目中,我采用的是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方法源码如下:

@Override
public 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返回一个唯一的值,因此重写该方法如下:

@Override
public long getItemId(int position) {
	return mFragments.get(position).hashCode();
}

之后调用pagerAdapter的notifyDataSetChanged方法就可以实现Fragment的刷新。

你可能感兴趣的:(android)