关于ViewPager清除已加载Fragment,重新创建新的Fragment的方法

最近在项目中使用ViewPager+Fragment实现左右两个滑动切换界面。但是遇到一个问题:在不退出当前Activity的情况下,重新加载Fragment,却得到了空白界面,并没有生成新的Fragment添加进去。

这个问题可能是由于旧的Fragment没有被清除导致的。

查看了 FragmentPagerAdapter 类的创建实例的函数 instantiateItem :

@NonNull
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        if (this.mCurTransaction == null) {
            this.mCurTransaction = this.mFragmentManager.beginTransaction();
        }

        long itemId = this.getItemId(position);
        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = this.mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            this.mCurTransaction.attach(fragment);
        } else {
            fragment = this.getItem(position);
            this.mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId));
        }

        if (fragment != this.mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
            fragment.setUserVisibleHint(false);
        }

        return fragment;
    }

我们看到这个函数会先检查是否已经存在了这样一个Fragment,如果不存在才会去调用 getItem 方法产生一个新的Fragment。所以我们可以利用类似的方法先去FragmentManager中清除对应的Fragment,然后再让适配器重新加载新Fragment。如下我们重写 FragmentPagerAdapter 类:

public class ViewMaterialFragmentPagerAdapter extends FragmentPagerAdapter {

    private FragmentManager mFragmentManager;
    private FragmentTransaction mCurTransaction;
    private Context mContext;
    private List mFragmentArrayList;
    private int[] pagerTitles = new int[]{R.string.text_material_qr_code, R.string.text_material_list};


    public ViewMaterialFragmentPagerAdapter(FragmentManager fm, Context ctx, List fragments) {
        super(fm);
        mFragmentManager = fm;
        mContext = ctx;
        mFragmentArrayList = fragments;
    }


    @Override
    public Fragment getItem(int i) {
        return mFragmentArrayList.get(i);
    }

    @Override
    public int getCount() {
        return mFragmentArrayList.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mContext.getString(pagerTitles[position]);
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        return super.instantiateItem(container, position);
    }

    /**
     * 清除缓存fragment
     * @param container ViewPager
     */
    public void clear(ViewGroup container){
        if (this.mCurTransaction == null) {
            this.mCurTransaction = this.mFragmentManager.beginTransaction();
        }

        for(int i=0;i

代码重点是 clear 方法,只要在需要销毁已经加载过得Fragment的地方,调用这个clear方法,再让ViewPager重新设置适配器即可。

pagerAdapter.clear(mViewPager);

mViewPager.setAdapter(pagerAdapter);

clear 方法中的 makeFragmentName 方法,可以在 FragmentPagerAdapter 类源码中找到,此处的makeFragmentName与源码中一模一样,只是由于这个方法在源码中私有的,我就暂且复制过来使用吧,当然也可以使用反射调用。

 

############ 好了,调大音量,听首歌吧 ~ ###############

关于ViewPager清除已加载Fragment,重新创建新的Fragment的方法_第1张图片

你可能感兴趣的:(Android,移动开发,Java)