Fragment的API學習筆記

PS:文章主要是博主自學源碼時記下來的新的筆記,很多東西都是自己的理解,不一定對,更不是教學文章。歡迎一起探討,不歡迎冷嘲熱諷,Thanks♪(・ω・)ノ~

源碼及API地址:https://developer.android.google.cn/reference/android/app/Fragment?hl=zh-cn

一、概況

頭部主要記住Fragment繼承自Object類,在Android3.0(API11)版本開始使用,在Android9.0(API28)被廢棄……(剛學就被廢了,真的sui~)

二、介紹

Fragment這個類是被放置在Activity中,用來充當用戶界面或者行爲的一個小碎片。各個Fragment之間是通過FragmentManager來相互聯繫的,而FragmentManager是通過Activity或者Fragment類中的getFragmentManager()方法獲取得到的。

Fragment這個類可以通過很多途徑達到各種各樣的效果。它的核心在一個運行較大的Activity的特殊操作或者界面中得以體現(意思就是當一個Activity越大Fragment在其中越能體現出它的價值)。Fragment類是緊密依附於Activity的,不能單獨運行。儘管Fragment有自己的生命週期,但是也要受到Activity的影響:比如當Activity停止運行時(就是onStop()唄),Activity中的所有Fragment也就都無法啓動,又比如當Activity被銷燬時(就是onDestory()唄),那麼這個Activity所包含的所有Fragment也要統統被銷燬。

所有的Fragment的子類必須要包含一個無參的構造函數,因爲在運行環境中當一個類需要被重新實例化時,尤其是恢復階段,就需要尋找這個無參的構造函數才能進行實例化,如果沒有找到,就會在一些恢復階段報RuntimeException異常;

三、內容

從四個方面進行介紹:

1.Older Platforms

就是說Fragment在Android3.0,HONEYCOMB這個版本被提出來的,對更早的版本可以用FragmentActivity進行兼容;

2.Lifecycle

儘管Fragment的生命週期依附在所屬的Activity中,但也有自己獨有的生命週期。包括像Activity的一些基本的生命週期比如“onResume()”,Fragment與Activity的交互、對UI的生成同意很重要。(這段沒太看懂,反正是爲了說明Fragment有着自己的生命週期,並且這些週期與Activity交互以及UI有關聯)

下面闡述Fragment生命週期:

文檔把生命週期分成了兩塊,一塊是綁定創建Fragment,一塊是銷燬解綁Fragment;

    用一張圖片表示:

    onAttach():Fragment與Activity關聯時調用;

    onCreate():初始化Fragment調用;

    onCreateView():Fragment綁定UI視圖調用;

    onActivityCreated():Fragment在依賴的Activity的onCreate()返回後調用;

    onStart():顯示Fragment界面視圖;

    onResume():正常運行時,與用戶交互;

    onPause():Fragment長時間不交互,或者依賴的Activity被Pause了,或者被一個Fragment通過修改時;

    onStop():Fragment長時間不可見,或者依賴的Activity被Stop了,或者被一個Fragment通過修改時;

    onDestoryView():當綁定了Fragment的UI視圖被移除時調用;

    onDestory():最終的清理;

    onDetach():與Activity解綁時調用;

 

PS:onDestroyView()中釋放資源,例如ButterKnife在onCreateView()時通過Unbinder對象unbinder=ButterKnife.bind(this,view)綁定,在onDestoryView()中進行unbinder.unbind()解綁。

3.Layout

靜態調用

Fragment可以通過<fragment>標籤直接嵌入進Activity的XML佈局中,並聲明要調用哪個Fragment類,這裏'class'屬性也可以使用'android:name'替換。

MainActivity類及其佈局:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/fragment"
        class="com.joseph.fragmenttest.MainFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"/>

</RelativeLayout>

MainFragment類及其佈局:

public class MainFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main,container,false);
        return view;
    }
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is Fragment"/>
</RelativeLayout>

靜態調用Fragment效果:

 

ListFragment

下面源碼緊接着介紹了ListFragment的使用,但是它只貼出了部分代碼,想要跑起來這個demo要簡單改動一下。

源碼總共有四塊。

1、新建兩個Fragment(TitlesFragment、DetailsFragment)把上面兩大塊代碼貼進去。

2、新建個DetailsActivity類直接把第三塊源碼貼進去。

3、最後一塊是MainActivity的橫屏佈局。而豎屏佈局只用寫一個fragment,如下:

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

    <fragment
        android:id="@+id/titles"
        android:name="你的包名.TitlesFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

4、這時候還要建一個Shakespeare類作爲數據源,如下所示:

public class Shakespeare {
    public static ArrayList<String> TITLES = new ArrayList<String>();
    public static  ArrayList<String> DIALOGUE = new ArrayList<String>();

    static {
        for (int i = 0; i < 50; i++) {
            TITLES.add("這是第"+(i+1)+"的Item");
            DIALOGUE.add("這是第"+(i+1)+"的Details");
        }
    }
}

然後有些小問題的地方稍微改改就能跑起來了。大致的效果就是豎屏時,只顯示一個TitlesFragment列表,點擊會跳轉到DetailsActivity顯示具體的信息,橫屏時DetailsActivity會自己finish掉,回到MainActivity並調用橫屏佈局,左邊TitlesFragment,右邊是DetailsFragment。

這裏有一點小優化就是把TitlesFragment代碼裏的

getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);

提出到括號前面,否則當你第一次豎屏點擊一個item後橫過來,高亮顯示的是對應的item,但是當你繼續豎屏點擊其他item後再橫屏,高亮顯示的還是第一次點擊的item。奈何個人水平有限,研究了半天不知道具體原因,個人懷疑是和adapter中調用的simple_list_item_activated_1中textview的background有關。感興趣的可以研究研究,這裏點到爲止。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章