处理viewpager、fragment的回收问题

来源:互联网 发布:js鼠标移动后单击 编辑:程序博客网 时间:2024/05/18 03:40

现在对处理viewpager、fragment使用过程中的回收问题,做一下记录



首先看下初始化fragment初始化的代码,对成员变量FragmentA、fragmentB进行赋值,并设置viewpager的adapter

伪代码:

private void initFragment() {    mFragmentA = FragmentA.newInstance();    mFragmentB = FragmentB.newInstance();    fragments = new ArrayList<>();    fragments.add(mFragmentA);    fragments.add(mFragmentB);    mFragmentAdapter = new HomeFragmentAdapter(this,fragments);    mViewPager.setAdapter(mFragmentAdapter);}



再看fragmentPagerAdapter源码

在对fragment绑定的时候,会先findFragmentByTag,如果之前有被回收的fragment,会进行复用,也就是说不会执行新生成的fragment.attach(),相当于新的fragment是没有用的,但是我们的成员变量指向的确实这个新生成的fragment。


@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;}

解决:在onRestoreInstance当中对旧的fragment重新引用

示意代码:

@Overridepublic void onRestoreInstanceState(Bundle savedInstanceState) {    super.onRestoreInstanceState(savedInstanceState);    Fragment fragmentFirst = getSupportFragmentManager().findFragmentByTag(makeFragmentName(mViewPager.getId(), 0));    if (fragmentFirst != null) {       mFragmentA = (FragmentA) fragmentFirst;    }    Fragment fragmentSecond = getSupportFragmentManager().findFragmentByTag(makeFragmentName(mViewPager.getId(), 1));    if (fragmentSecond != null) {        mFragmentB=  (FragmentB)fragmentSecond;    }}/** * 参考fragmentPagerAdapter中的寻找fragment的方法 */private static String makeFragmentName(int viewId, long id) {    return "android:switcher:" + viewId + ":" + id;}


0 0