處理viewpager、fragment的回收問題

現在對處理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。


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

解決:在onRestoreInstance當中對舊的fragment重新引用

示意代碼:

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章