自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

FragmentPagerAdapter和FragmentStatePagerAdapter的區(qū)別

移動開發(fā) Android
FragmentPagerAdapter和FragmentStatePagerAdapter在Android開發(fā)中都是用于與ViewPager配合使用的適配器,而主要區(qū)別在于它們對Fragment生命周期的管理方式。

FragmentPagerAdapter和FragmentStatePagerAdapter在Android開發(fā)中都是用于給ViewPager進行數(shù)據(jù)適配的適配器,在使用和管理Fragment的方式上兩者存在顯著的區(qū)別。

FragmentPagerAdapter在切換Fragment時,不會銷毀Fragment,而只是調(diào)用事務中的detach方法。因此Fragment的視圖(view)會被銷毀,而Fragment的實例會保留在FragmentManager中。通過這種方式創(chuàng)建的Fragment一直不會被銷毀,適用于一些靜態(tài)的Fragment,例如一組tabs。這也可能導致在Fragment數(shù)量較大時,應用程序占用過多資源。

FragmentStatePagerAdapter在切換不同的Fragment時,會銷毀不再需要的Fragment。在銷毀Fragment前,會先將Fragment的狀態(tài)信息(通過onSaveInstanceState(Bundle)方法保存)保存在Bundle中。切換回原來的頁面后,保存的狀態(tài)可用于恢復生成新的Fragment。適用于頁面數(shù)量較大或需要動態(tài)加載和銷毀Fragment的場景,能有效地管理內(nèi)存使用。

FragmentPagerAdapter源碼

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

在instantiateItem方法中,主要是將Fragment添加到FragmentManager中。未添加到FragmentManager中的執(zhí)行add操作,已添加到FragmentManager中的只進行attach操作。

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    if (mCurTransaction == null) {
        mCurTransaction = mFragmentManager.beginTransaction();
    }
    if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object + " v=" + ((Fragment)object).getView());
    mCurTransaction.detach((Fragment)object);
}

在destroyItem方法中,只是進行detach操作。detach操作并不會將Fragment銷毀,F(xiàn)ragment依舊是由FragmentManager進行管理。

FragmentStatePagerAdapter源碼

 @Override
public Object instantiateItem(ViewGroup container, int position) {
    if (mFragments.size() > position) {
        Fragment f = mFragments.get(position);
        if (f != null) {
            return f;
        }
    }
    if (mCurTransaction == null) {
        mCurTransaction = mFragmentManager.beginTransaction();
    }
    Fragment fragment = getItem(position);
    if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
    if (mSavedState.size() > position) {
        Fragment.SavedState fss = mSavedState.get(position);
        if (fss != null) {
            fragment.setInitialSavedState(fss);
        }
    }
    while (mFragments.size() <= position) {
        mFragments.add(null);
    }
    fragment.setMenuVisibility(false);
    fragment.setUserVisibleHint(false);
@
    mFragments.set(position, fragment);
    mCurTransaction.add(container.getId(), fragment);
    return fragment;
}

FragmentStatePagerAdapter是通過一個mFragments數(shù)組來存儲Fragment的,通過mSavedState數(shù)組來存儲Fragment銷毀時的狀態(tài),通過position獲取到的Fragment可能為空(被回收),如果為空,則會再次調(diào)用getItem方法重新創(chuàng)建新的Fragment,然后將mSavedState中存儲的狀態(tài)重新賦予這個新的Fragment, 達到Fragment恢復的效果。

 @Override
public void destroyItem(ViewGroup container, int position, Object object) {
    Fragment fragment = (Fragment) object;
    if (mCurTransaction == null) {
        mCurTransaction = mFragmentManager.beginTransaction();
    }
    if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object + " v=" + ((Fragment)object).getView());
    while (mSavedState.size() <= position) {
        mSavedState.add(null);
    }
    mSavedState.set(position, fragment.isAdded() ? mFragmentManager.saveFragmentInstanceState(fragment) : null);
    mFragments.set(position, null);
    mCurTransaction.remove(fragment);
}

當item在頁面中不可見時,該Fragment的狀態(tài)會先被保存到mSavedState中,而Fragment實例則會被銷毀。

總結(jié)

FragmentPagerAdapter和FragmentStatePagerAdapter在Android開發(fā)中都是用于與ViewPager配合使用的適配器。

相同點:

  • 繼承自PagerAdapter:都繼承自PagerAdapter,基本功能和用法一樣。
  • 管理Fragment:都是用來管理Fragment的適配器,使ViewPager能夠展示一系列的Fragment。
  • 保持當前和前后Fragment狀態(tài):在顯示當前Fragment的同時,Adapter會提前初始化后一個Fragment,并把當前Fragment的前一個Fragment保存在內(nèi)存中。

不同點:

(1) Fragment銷毀策略:

  • FragmentPagerAdapter:不會銷毀已經(jīng)創(chuàng)建的Fragment實例,而是保存在內(nèi)存中。當Fragment不再可見時,只會調(diào)用detach方法,銷毀Fragment的視圖(View),保留Fragment的實例。切換回之前的Fragment,可以快速重新綁定視圖,而不需要重新創(chuàng)建Fragment實例。這種方式適用于Fragment數(shù)量較少,且不需要頻繁創(chuàng)建和銷毀的場景。
  • FragmentStatePagerAdapter:在不再需要某個Fragment時完全銷毀。當Fragment滑出屏幕范圍后,實例和視圖都會被銷毀。切換回該Fragment時,會重新創(chuàng)建Fragment實例和視圖。這種方式適用于Fragment數(shù)量較多,或者需要動態(tài)加載和銷毀Fragment的場景,以避免占用過多內(nèi)存。

(2) 狀態(tài)保存與恢復:

  • FragmentStatePagerAdapter:在銷毀Fragment之前,會在onSaveInstanceState(Bundle)方法中保存Fragment的狀態(tài)信息。切換回原來的Fragment時,可以使用這些保存的狀態(tài)信息來恢復Fragment的狀態(tài)。
  • FragmentPagerAdapter:由于不會銷毀Fragment實例,不需要在銷毀前保存狀態(tài),也不需要在恢復時重新加載狀態(tài)。

FragmentPagerAdapter和FragmentStatePagerAdapter的主要區(qū)別在于它們對Fragment生命周期的管理方式。前者保留Fragment實例,適用于Fragment數(shù)量較少且不需要頻繁創(chuàng)建和銷毀的場景;后者在不再需要時銷毀Fragment,適用于Fragment數(shù)量較多或需要動態(tài)加載和銷毀的場景。

責任編輯:趙寧寧 來源: 沐雨花飛蝶
相關推薦

2021-08-04 08:33:59

TypeScriptConst Readonly

2020-08-12 23:21:49

平臺即服務PaaSaPaaS

2011-03-03 09:55:34

forwardredirect

2010-07-30 14:09:30

FlexFlash

2018-11-14 09:46:33

DoSDDoS攻擊

2009-12-03 10:12:24

LinuxUnix

2011-06-08 11:02:14

GetPost

2020-07-09 10:53:05

MPLSIP網(wǎng)絡

2018-09-20 16:10:48

CookiesSession前端

2010-08-12 15:30:27

FlexFlash

2015-09-23 10:00:47

OLTPOLAP

2019-01-14 15:44:11

CoinToken區(qū)塊鏈

2011-05-26 15:52:31

sleep()wait()

2011-09-05 17:44:49

LinuxUnix

2009-07-06 15:34:56

JSP和Servlet

2009-07-14 15:01:02

AWT和Swing

2009-09-01 10:14:16

samba

2016-11-03 19:10:02

Linux操作系統(tǒng)

2011-04-19 15:11:40

typedefdefine

2009-07-08 17:59:51

JDK JRE
點贊
收藏

51CTO技術棧公眾號