目錄
一.Fragment詳解
一.Fragment基礎(chǔ)
1.Fragment
Fragment為什么會出現(xiàn),它其實(shí)是android3.0的時候引入的,可以翻譯為“碎片” “片段”起初它主要是給大屏幕上設(shè)備上更靈活的展現(xiàn)UI所設(shè)計(jì)的。
如上圖,左邊展現(xiàn)的是平板電腦上的使用場景,而在實(shí)際項(xiàng)目開發(fā)中,使用頻率更高的是右邊的場景,右邊的圖中,左右兩個Activity包含了各自的Fragment,Activity A通過 方法啟動 Activity B時,實(shí)際上啟動的是Fragment B。所以說我們一般會在一個Activity中嵌套多個Fragment,來進(jìn)行UI 數(shù)組間的切換,一般用到的模式是Fragment+ViewPager。 Fragment相比Activity 更節(jié)省內(nèi)存,同時UI的切換效果更加舒適, Fragment有自己的生命周期,同時它可以動態(tài),靈活的加載Activity。但是Fragment并不是像Activity一樣完全獨(dú)立的,它雖然有自己的生命周期,但它必須依附Activity,同時它要加載到Activity當(dāng)中。
2.Fragment加載到Activity的兩種方式
1.靜態(tài)添加:添加Fragment到Activity的布局文件當(dāng)中
2.動態(tài)添加:動態(tài)在Activity中添加Fragment
靜態(tài)加載就是把Fragment作為一個xml的標(biāo)簽加到Activity布局當(dāng)中。
常用的方法就是動態(tài)添加
首先在布局文件中放一個FrameLayout,方便在Activity中可以動態(tài)添加不同的Fragment
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.bsoft.fragmentdemo.MainActivity">
<FrameLayout
android:id="@+id/fl_demo"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
然后在Activity中動態(tài)添加Fragment
//步驟1 : 添加FragmentTransaction的實(shí)例
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
//步驟2 :用add()方法加上Fragment的對象FirstFragment
FirstFragment firstFragment = new FirstFragment();
transaction.add(R.id.fl_demo,firstFragment);
//步驟3 : 調(diào)用commit()方法使FragmentTransaction實(shí)例的改變生效。
transaction.commit();
3.FragmentPagerAdapter與FragmentStatePagerAdapter區(qū)別
FragmentPagerAdapter適用于頁面較少的情況。
FragmentStatePagerAdapter適用于頁面較多的情況。
FragmentPagerAdapter源碼中的destroyItem方法:
@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);
}
它最后一行調(diào)用的是 FragmentTransaction的detach方法。detach并不是真正的內(nèi)存回收,它只是把Fragment的UI和Activity的UI脫離開來,并不回收內(nèi)存。
FragmentStatePagerAdapter源碼中的destroyItem方法:
@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);
}
mCurTransaction.remove(fragment),在FragmentStatePagerAdapter里面是真正釋放了fragment內(nèi)存。所以說明了FragmentStatePagerAdapter比FragmentPagerAdapter更節(jié)省內(nèi)存的。
二.Fragment生命周期
1.Fragment生命周期與Activity生命周期的對比
2.Fragment從啟動到銷毀生命周期全過程
跟記憶Activity生命周期一樣,F(xiàn)ragment的生命周期也需要靈活的來記憶
Fragment 創(chuàng)建時會調(diào)用:
onAttach() -> onCreate() -> onCreateView() -> onActivityCreated()
onAttach():在Fragment 與 Activity關(guān)聯(lián)之后所回調(diào)的
onCreate() : 是在初次創(chuàng)建Fragment時候調(diào)用
注:這里的onCreate方法看起來和Activity中的onCreate方法一樣。但是這個方法只是用來創(chuàng)建Fragment,此時的Activity還并沒有被創(chuàng)建完成。
onCreateView():是系統(tǒng)在Fragment首次繪制用戶界面時候調(diào)用的這個方法
注:如果想要為這個Fragment繪制UI界面,從該方法返回的View必須是Fragment布局的根視圖。
在onCreateView()方法調(diào)用之后會調(diào)用onViewCreated()方法
onViewCreated():表明Fragment的UI界面已經(jīng)完全繪制好了,調(diào)用這個方法可以初始化控件資源。
onActivityCreated():這個方法是在Activity的onCreat()方法調(diào)用之后才可以被調(diào)用。也就是在Activity被渲染繪制成功以后的調(diào)用方法
Fragment被用戶可見后調(diào)用
onStart() -> onResume()
onStart():表示Fragment可見了
onResume():表示Fragment可以跟用戶進(jìn)行交互了(點(diǎn)擊,滑動等操作)
到這里已經(jīng)完成了Fragment從啟動到展現(xiàn)的操作。
當(dāng)要Fragment被銷毀
onPause() -> onStop() -> onDestroyView() -> onDestroy() -> onDetach()
onPause():系統(tǒng)將此方法作為用戶離開Fragment的第一個信號(但并不總是意味著此Fragment會被銷毀)進(jìn)行調(diào)用。 通常可以在此方法內(nèi)確認(rèn)在當(dāng)前用戶會話結(jié)束后仍然有效的任何更改(因?yàn)橛脩艨赡懿粫祷兀?br> onDestroyView():表示這個Fragment即將結(jié)束,會被保存。
onDetach():Fragment和Activity解除關(guān)聯(lián)的時候調(diào)用
到此,我們完整的走完一Fragment的生命周期。
還有一些其他場景時Fragment調(diào)用的生命周期
屏幕滅掉
onPause() -> onSaveInstanceState() -> onStop()
屏幕解鎖
onStart() -> onResume()
切換到其他Fragment
onPause() -> onStop() -> onDestroyView()
切換回本身的Fragment
onCreateView() -> onActivityCreated() -> onStart() -> onResume()
回到桌面
onPause() -> onSaveInstanceState() -> onStop()
回到應(yīng)用
onStart() -> onResume()
三.Fragment通信
1.在Fragment中調(diào)用Activity中的方法
(getActivity)只要調(diào)用getActivity方法,就可以獲取到Activity中的方法
2.在Activity中調(diào)用Fragment中的方法
(接口回調(diào))在Fragment中創(chuàng)建個接口,然后由Activity實(shí)現(xiàn)。這樣就能完成在Activity中調(diào)用Fragment中的方法
3.在Fragment中調(diào)用Fragment中的方法
(findFragmentById)首先可以通過 getActivity獲取Activity的方法,然后通過findFragmentById獲取到Activity所對應(yīng)的另外一個Fragment的方法,這樣就能完成Fragment與Fragment的通信
四.Fragment的replace,add,remove方法
replace():替換Fragment實(shí)例。
add():將一個Fragment實(shí)例添加到添加到Activity最上層
remove():將Fragment實(shí)例從Activity隊(duì)列中刪除