學習筆記| AS入門(六) 碎片Fragment

安卓自3.0開始引入Fragment的概念,主要是為了能在不同分辯率屏幕上進行更為動態和靈活的UI設計,讓程序更加合理和充分利用大屏幕空間。本篇將學習Fragment以下幾個知識點:

  • Fragment概要
  • Fragment生命周期
  • 加載Fragment方法
    • 靜態加載
    • 動態加載
  • Fragment與Activity之間通信

1.Fragment概要

學習Fragment的時候可以聯系之前學習過的Activity,因為它們有很多相似點:都可包含布局,有自己的生命周期,Fragment可看似迷你活動。正如Fragment的名字--碎片,它的出現是為了解決Android碎片化 ,它可作為Activity界面的組成部分,可在Activity運行中實現動態地加入、移除和交換。一個Activity中可同時出現多個Fragment,一個Fragment也可在多個Activity中使用。活動和碎片像極了夫妻, 雖然緊密聯系但是又有獨立空間,在一起讓彼此變得更好。

下面這個非常經典的例子更直觀地說明了Fragment作用:

2.Fragment生命周期

先來看官方文檔提供的有關Fragment生命周期的圖片。

是不是能發現Fragment和Activity的生命周期太相似了,現在只需要再介紹幾個Activity中沒講過的新方法:

onAttach():當Fragment和Activity建立關聯時調用
onCreateView():當Fragment創建視圖時調用
onActivityCreated():當與Fragment相關聯的Activity完成onCreate()之后調用
onDestroyView():在Fragment中的布局被移除時調用
onDetach():當Fragment和Activity解除關聯時調用

在上圖中畫了幾條線,可以看到Fragment周期中的狀態幾乎都是成對出現的,所以不難理解下圖幾種變化下Fragment生命周期方法的調用順序了。

加載到Activity中的Fragment在各種變化下方法的調用順序更值得注意。需要提一句的是,Activity的FragmentManager負責調用隊列中Fragment的生命周期方法,只要Fragment的狀態與Activity的狀態保持了同步,托管Activity的FragmentManager便會繼續調用其他生命周期方法以繼續保持Fragment與Activity的狀態一致。

Fragment生命周期與Activity生命周期的一個關鍵區別就在于,Fragment的生命周期方法是由托管Activity而不是操作系統調用的。Activity中生命周期方法都是protected,而Fragment都是public,也能印證了這一點,因為Activity需要調用Fragment那些方法并管理它。

3.加載Fragment方法

現在就來學習如何在Activity中加載Fragment。

(1)靜態加載:在托管Activity的layout文件中聲明Fragment

靜態加載Fragment大致過程如圖,分成四步:

下面通過一個簡單的例子感受Fragment靜態加載到Activity的過程。

第一步:新建frag_layout.xml,為Fragment指定一個布局,這里簡單的放一個TextView和一個Button。

第二步:新建一個MyFragment類并繼承Fragment,這里引用android.app包下的就可以,另一個包下主要用于兼容低版本的安卓系統。然后重寫onCreateView()方法,這個方法里通過LayoutInflater的inflate()方法將剛剛定義的frag_layout布局加載進來并得到一個View,再return這個View。

第三步:新建mian.xml,作為Activity的布局,使用< fragment>標簽添加碎片,并且一定要有android:name屬性且值為被加載的Fragment類的包名.類名完整形式。

第四步:在MainActivity中加載main布局。現在MyFragment就完成了靜態加載到MainActivity中,這時碎片里的控件自然也是活動的一個部分,可直接在活動中獲取到Button的實例,來注冊點擊事件了。

運行一下看看能不能達到效果:

(2)動態加載:在托管Activity通過代碼動態添加

動態加載的代碼也非常簡單,直接看例子。修改main.xml,將整個< fragment>刪掉。但還保留一個LinerLayout的空間并且還給了Id,為何這樣做?馬上揭秘。

接下來在MainActivity中添加幾行代碼:

可將整個過程大致分為三個步驟:

第一步,先用getFragmentManager()方法獲取一個FragmentManager對象,再通過它的beginTransaction()獲取一個FragmentTransaction的實例。

第二步,用beginTransaction.add()方法將MyFragemnt實例添加到main布局里LinearLayout里,終于知道之前鋪墊的Id是怎么回事了。一定要注意,add()方法里的第一個參數是容器視圖資源Id,而不是layout。容器視圖資源Id有兩個作用:告知FragmentManager,碎片視圖應該出現在活動視圖的什么地方;它也是FragmentManager隊列中碎片的唯一標識符。而靜態加載時碎片的唯一標識符正是在活動布局里< fragment>下的id。

第三步:調用beginTransaction.commit()提交。另外,如果允許用戶通過按下返回按鍵返回到前一個Fragment狀態,在調用commit()之前先調用addToBackStack(true)方法。

這里注意到動態加載進來的Fragment里的控件并不能直接在活動中findViewById得到,那么如何實現點擊效果呢,學完下一個知識點就有辦法了。

4.Fragment與Activity之間通信

在活動中可以通過調用FragmentManagerfindFragmentById()方法來得到相應碎片的實例,繼而可以調用碎片里的方法。以上面demo舉例,如果想得到靜態加載碎片的實例,可在MainActivity添加代碼如下:

MyFragment myFragment = (MyFragment)getFragmentManager(). findFragmentById(R.id.fragment);

如果想得到動態加載碎片的實例,代碼如下:

MyFragment myFragment = (MyFragment)fragmentManager(). findFragmentById(R.id.layout);

在碎片中也可以通過調用getActivity()方法來得到和當前碎片相關聯的活動實例,這樣調用活動里的方法就變得輕而易舉了。比如想在MyFragment得到MainActivity的實例:

MainActivity activity=(MainActivity)getActivity();

于是碎片和活動可以很方便地進行通信了。再想一想碎片和碎片之間如何進行通信?先在一個碎片中可以得到與它相關聯的活動,然后再通過這個活動去獲取另外一個碎片的實例,這樣實現了不同碎片之間的通信了。

現在你有沒有想到解決之前那個問題的辦法呢?可以這樣做,修改MyFragment,代碼如下圖所示:

現在按鈕點擊就又有響應了!其實在實際開發中,如果某一板塊每次用到都需要相同的功能,就完全可以在碎片中實現需求,而不必在活動中重復代碼,這樣可以提高代碼的復用性。

> 下一篇預告:數據存儲篇

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容