Android 你需要掌握的知識(三)

目錄

Fragment.png

一.Fragment詳解

一.Fragment基礎(chǔ)

1.Fragment

Fragment為什么會出現(xiàn),它其實(shí)是android3.0的時候引入的,可以翻譯為“碎片” “片段”起初它主要是給大屏幕上設(shè)備上更靈活的展現(xiàn)UI所設(shè)計(jì)的。

圖片來源于網(wǎng)絡(luò).png

如上圖,左邊展現(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生命周期

圖片來源于網(wǎng)絡(luò).png
1.Fragment生命周期與Activity生命周期的對比
圖片來源于網(wǎng)絡(luò).png
2.Fragment從啟動到銷毀生命周期全過程
Fragment從啟動到銷毀生命周期全過程.png

跟記憶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ì)列中刪除

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,791評論 6 545
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,795評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,943評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,057評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,773評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,106評論 1 330
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,082評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,282評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,793評論 1 338
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,507評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,741評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,220評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,929評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,325評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,661評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,482評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,702評論 2 380

推薦閱讀更多精彩內(nèi)容