從0系統(tǒng)學(xué)Android--4.2 Fragment 生命周期

從0系統(tǒng)學(xué)Android--

image

image

本系列文章目錄更多精品文章分類

本系列持續(xù)更新中.... 初級階段內(nèi)容參考《第一行代碼》

4.3 碎片的生命周期

碎片也有自己的生命周期,并且和 Activity 的生命周期還很像。

4.3.1 碎片的狀態(tài)和回調(diào)

  1. 運行狀態(tài)

    當一個碎片可見,并且它所關(guān)聯(lián)的活動正處在運行狀態(tài)時,這個碎片也處于運行狀態(tài)。

  2. 暫停狀態(tài)

    當一個 Activity 進入暫停狀態(tài)時,與它相關(guān)聯(lián)的可見碎片就會進入到暫停狀態(tài)。

  3. 停止狀態(tài)

    當一個活動進入了停止狀態(tài)時,與他關(guān)聯(lián)的碎片就會進入到停止狀態(tài),或者通過調(diào)用 FragmentTransactionremove()或者 replace() 方法將碎片從活動中移除,前提是在事務(wù)提交之前調(diào)用 addToBackStack() 方法,這時碎片也會進入到停止狀態(tài)。

    // 前提當前的 Activity 處于運行狀態(tài)。
    Fragment A = new Fragment();
    FragmentManager fragmentManager = getSupportFragmentManger();
    FrgmentTransaction fragmentTransaction = fragmentManger.beginTransaction();
    fragmentTransaction.replace(R.id.framelayout,A);// 這個時候 Fragment A應(yīng)該是處于運行狀態(tài)的。
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();
    Fragment B = new Fragment();
    fragmentTransaction.replace(R.id.framelayout,B);// 這個時候 AFragment 的狀態(tài)時停止狀態(tài)的。
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();
    

進入停止狀態(tài)的碎片對于用戶來說是完全不可見的,有可能會被系統(tǒng)回收。

  1. 銷毀狀態(tài)

    碎片總是依附于 Activity 而存在的,因此當 Activity 被銷毀時,相關(guān)聯(lián)的碎片就會進入銷毀狀態(tài)?;蛘咄ㄟ^調(diào)用 FragmentTransaction()reove() 、replace() 方法將碎片從 Activity 中移除,并且在事務(wù)提交之前沒有調(diào)用 addToBackStatck() 方法,這時的碎片也會進入到銷毀狀態(tài)。

  • onAttach() 當碎片和 Activity 建立關(guān)聯(lián)的時候使用
  • onCreateView() 為碎片創(chuàng)建視圖(加載布局)時調(diào)用
  • onActivityCreated() 確保與碎片相關(guān)聯(lián)的 Activity 一定已經(jīng)創(chuàng)建完畢的時候調(diào)用。
  • onDestroyView() 當與碎片關(guān)聯(lián)的視圖被移除的時候調(diào)用
  • onDetach() 當碎片和 Activity 解除關(guān)聯(lián)的時候調(diào)用。
image

4.3.2 體驗碎片的生命周期

就是在上一個例子的基礎(chǔ)上,在每個方法匯總打印一下,觀察一下效果就好了。

這里給宿主 FragmentBaseActivity 和 靜態(tài)添加到 Activity 中的 Fragment 的生命周期方法里面添加打印。效果:

image

在碎片中,你也是可以通過 onSaveInstanceState() 方法來保存數(shù)據(jù),因為進入停止狀態(tài)的碎片也是有可能被系統(tǒng)在內(nèi)存不足的情況下收回的。保存下來的數(shù)據(jù)在 onCreateView()onActivityCreated()onCreate() 中都可以獲取到

4.4 動態(tài)加載布局的技巧

程序如何能夠根據(jù)設(shè)備的分辨率或屏幕大小在運行時來決定加載哪個布局呢?

4.4.1 使用限定符

經(jīng)常使用平板電腦我們會發(fā)現(xiàn)有些應(yīng)用都是采用雙頁模式(程序會在左側(cè)面板上顯示一個包含子項的列表,在右側(cè)的面板上顯示內(nèi)容)。這是因為平板電腦屏幕的大的原因,完全可以顯示兩頁的內(nèi)容。但是手機就不行了,屏幕比較小,只能顯示一頁的內(nèi)容。

那么怎么樣才能在運行時判斷程序應(yīng)該使用雙頁模式還是單頁模式呢?這就需要限定符(Qualifiers)實現(xiàn)。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<fragment
    android:layout_width="match_parent"
    android:layout_height="match_parent"
  
  android:name="com.example.firstcode.fourth_chapter.LeftFragment"/>
</LinearLayout>

這個時候讓它充滿了整個頁面。

在 res 目錄下新建 layout_large 文件夾,在這個文件夾新建一個布局,也叫做 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<fragment
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:name="com.example.firstcode.fourth_chapter.LeftFragment"
    android:id="@+id/fg_left"/>
 <fragment
     android:layout_width="0dp"
     android:layout_height="match_parent"
     android:layout_weight="1"
     android:name="com.example.firstcode.fourth_chapter.RightFragment"
     android:id="@+id/fg_right"/>
</LinearLayout>

其中 large 就是一個限定符,那些屏幕被認為是large 的設(shè)備就會自動加載 layout-large 文件下的布局,而小屏幕的設(shè)備還是會加載 layout 下的布局。

Android 中一些常見的限定符

image

4.4.2 使用最小寬度限定符

large 到底指多大呢?有時候我們需要更加靈活,不管它們是不是被系統(tǒng)認定為 large 這個時候就可以使用最小寬度限定符(Smallest-width Qualifier)。

最小寬度限定符允許我們指定一個最小的值(以dp為單位),然后如果屏幕大于等于這個最小值則使用這個文件夾內(nèi)的布局,如果小于則使用默認布局

在 res 目錄新建 layout-sw600dp 文件,在這個文件夾創(chuàng)建布局就可以了。

4.5 碎片的實踐----簡易版新聞應(yīng)用

首先我們要實現(xiàn)的效果是在普通手機上是單頁模式,也就是有一個新聞標題列表,點擊后進入下一個頁面(新聞詳情頁面)。

在平板電腦上效果是雙頁模式:效果如

image

試想我們是不是可以為手機和平板每個端提供一個應(yīng)用程序呢?如果這樣做的話會浪費很多的人力物力,因為這樣意味著要同時維護兩份代碼。

Fragment 的出現(xiàn)就是為了充分利用屏幕空間的。這里可以使用 Fragment 來很多的處理這個問題。

思路:通過限定符,在手機上面會加載直接標題列表的頁面,在平板上會加載列表和內(nèi)容頁面。

其中為了復(fù)用,標題列表和內(nèi)容頁面都應(yīng)該是一個 Fragment。這樣就達到了復(fù)用的效果。

實現(xiàn)代碼:MyGitHub/FirstCode/app/src/main/java/com/example/firstcode/fourth_chapter/news 包下

4.6 總結(jié)

Fragment 運用在要求充分利用屏幕資源的情況下

加載方式有靜態(tài)加載和動態(tài)加載。

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容