轉載請標明出處:【顧林海的博客】
前言
今天還是總結下Android中的小知識點Fragment,Fragment使用廣泛,有自己的生命週期(必須依附Activity),動態靈活的加載到Activity中去,Android 3.0 引入,常用模式有Fragment+ViewPager。
Fragment加載到Activity的兩種方式
- 添加Fragment到Activity的佈局文件當中。
- 在Activity的代碼中動態添加Fragment。
第一種方式雖然簡單但靈活性不夠。添加Fragment到Activity的佈局文件當中,就等同於將Fragment及其視圖與activity的視圖綁定在一起,且在activity的生命週期過程中,無法切換fragment視圖。
第二種方式比較複雜,但也是唯一一種可以在運行時控制fragment的方式(加載、移除、替換)。
第二種方式代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background">
<FrameLayout
android:id="@+id/id_fl_homepage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/id_bottom_menu" />
</RelativeLayout>
private static Fragment mContentFragment;
/**
* Fragment的切換
*
* @param fragment Fragment
*/
private void switchFragment(Fragment fragment) {
if (mContentFragment != fragment) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.hide(mContentFragment);
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
} else {
fragmentTransaction.add(R.id.id_fl_homepage, fragment);
}
fragmentTransaction.commitAllowingStateLoss();
mContentFragment = fragment;
}
}
FragmentPagerAdapter與FragmentStatePagerAdatper區別
FragmentPagerAdapter適用於頁面較少的情況下,FragmentStatePagerAdapter適用於頁面較多的情況下。
查看FragmentStatePagerAdapter源碼:
@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);
//真正的釋放了Fragment內存。
mCurTransaction.remove(fragment);
}
重點在最後一行,mCurTransaction.remove(fragment);表示釋放了Fragment內存。
再查看FragmentPageAdapter源碼:
@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);
}
同樣看最後一行調用了FragmentTransaction的detach方法,detach方法只是將Fragment UI和Activity UI脫離開,並不會回收內存。
Fragment生命週期
Fragment不是獨立,它依附於Activity,
Fragment與Activity生命週期對比圖:
Fragment之間的通信
- 在Fragment中調用Activity中的方法: getActivity。
- 在Activity中調用Fragment中的方法: 接口回調。
- 在Fragment中調用Fragment中的方法: findFragmentById
Fragment管理器:FragmentManager
FragmentManager方法:replace、add、remove。
replace作用是替換Fragment實例,add作用是添加Fragment實例,remove移除Fragment。