1. 程式人生 > >探究碎片Fragment(2)

探究碎片Fragment(2)

碎片的活動週期

活動中有的回撥方法,碎片 中幾乎都有,不過碎片還提供了一些附加的回撥方法,那我們就重點來看下這幾個回撥

  1. onAttach() 當碎片和活動建立關聯的時候呼叫
  2. onCreateView() 為碎片建立檢視(載入佈局)時呼叫
  3. onActivityCreated() 確保與碎片相關聯的活動一定已經建立完畢的時候呼叫
  4. onDestroyView() 當與碎片關聯的檢視被移除的時候呼叫
  5. onDetach() 當碎片和活動解除關聯的時候呼叫

在這裡插入圖片描述

在上一節的RightFragment的基礎上修改

public class RightFragment extends Fragment {
    public static final String TAG = "RightFragment";

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Log.d(TAG, "onAttach");
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView");
        View view = inflater.inflate(R.layout.right_fragment, container, false);
        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG, "onActivityCreated");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "onStop");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d(TAG, "onDestroyView");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d(TAG, "onDetach");
    }
}

重新執行 程式,這時觀察 LogCat中的列印資訊
在這裡插入圖片描述

然後點選 LeftFragment中的按鈕,此時列印資訊

在這裡插入圖片描述
由於 AnotherRightFragment替換了 RightFragment,此時的 RightFragment進入了停止狀 態,因此 onPause()、onStop()和 onDestroyView()方法會得到執行。當然如果在替換的時候沒 有呼叫 addToBackStack()方法,此時的 RightFragment 就會進入銷燬狀態,onDestroy()和 onDetach()方法就會得到執行

接著按下 Back鍵,RightFragment會重新回到螢幕
在這裡插入圖片描述


由於 RightFragment 重新回到了執行狀態,因此 onActivityCreated()、onStart()和 onResume()方法會得到執行。注意此時 onCreate()和 onCreateView()方法並不會執行,因為我 們藉助了 addToBackStack()方法使得 RightFragment和它的檢視並沒有銷燬

再次按下 Back鍵退出程式
在這裡插入圖片描述
依次會執行 onPause()、onStop()、onDestroyView()、onDestroy()和 onDetach()方法,最 終將活動和碎片一起銷燬

動態載入佈局的技巧

如果你經常使用平板電腦,應該會發現很多的平板應用現在都採用的是雙頁模式(程式 會在左側的面板上顯示一個包含子項的列表,在右側的面板上顯示內容),因為平板電腦的 螢幕足夠大,完全可以同時顯示下兩頁的內容,但手機的螢幕一次就只能顯示一頁的內容,因此兩個頁面需要分開顯示
那麼怎樣才能在執行時判斷程式應該是使用雙頁模式還是單頁模式呢?這就需要藉助 限定符(Qualifiers)來實現了。我們通過一個例子來學習一下它的用法,修改 剛才專案中的 activity_main.xml檔案

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/left_fragment"
        android:name="com.example.xx.myapplication.LeftFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

這裡將多餘的程式碼都刪掉,只留下一個左側碎片,並讓它充滿整個父佈局

接著在 res 目錄下新建 layout-large資料夾,在這個資料夾下新建一個佈局,也叫做 activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/left_fragment"
        android:name="com.example.xx.myapplication.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <fragment
        android:id="@+id/right_fragment"
        android:name="com.example.xx.myapplication.RightFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3" />
</LinearLayout>

layout/activity_main 佈局只包含了一個碎片,即單頁模式,而 layout-large/ activity_main佈局包含了兩個碎片,即雙頁模式
其中 large就是一個限定符,那些螢幕被認 為是 large的裝置就會自動載入 layout-large資料夾下的佈局,而小螢幕的裝置則還是會載入 layout資料夾下的佈局
在這裡插入圖片描述

在這裡插入圖片描述

這樣我們就實現了在程式執行時動態載入佈局的功能。
Android中一些常見的限定符可以參考下表
在這裡插入圖片描述

使用最小寬度限定符

在上一小節中我們使用 large限定符成功解決了單頁雙頁的判斷問題,不過很快又有一 個新的問題出現了,large到底是指多大呢?有的時候我們希望可以更加靈活地為不同裝置加 載佈局,不管它們是不是被系統認定為“large”,這時就可以使用最小寬度限定符 (Smallest-widthQualifier)了
最小寬度限定符允許我們對螢幕的寬度指定一個最小指(以 dp為單位) ,然後以這個最 小值為臨界點,螢幕寬度大於這個值的裝置就載入一個佈局,螢幕寬度小於這個值的裝置就 載入另一個佈局

在 res 目錄下新建 layout-sw600dp 資料夾,然後在這個資料夾下新建 activity_main.xml 佈局,這就意味著,當程式執行在螢幕寬度大於 600dp 的裝置上時,會載入 layout-sw600dp/ activity_main 佈局,當程式執行在螢幕寬度小於 600dp 的裝置上時,則仍然載入預設的 layout/activity_main佈局