2013年2月1日 星期五

Fragment與Activity間的資料傳遞

上篇討論了Fragment間的資料傳遞後,接著來討論Fragment與Activity間的資料傳遞。
HelloFragment這篇文章中的第二段提及了一個新聞列表及新聞內容範例。

上圖分別代表兩個Fragment,假如我們要寫出類似這個程式出來在資料的傳遞上該如何做呢? 以下提出兩個方法:
1. 當使用者點選新聞列表(Fragment 1)後資料直接傳遞到新聞內容(Fragment 2)顯示。
2. 當使用者點選新聞列表(Fragment 1)後Fragment 1把使用者所選擇的項目或標題告訴Activity;然後Activity再告訴Fragment 2,接著新聞內容(Fragment 2)顯示新聞資訊。

前者當然簡單容易就如同上一篇的方式可以輕而易舉的完成。但是,會寫出第二點當然是由原因的,在Google的 Android Developer網站中有一篇Communicating with Other Fragments文章,一開始前兩段這麼寫著:
為了重複使用Fragment UI元件,你應該建立一個完全獨立、模組化的佈局和行為的元件。一但你定義了這些可重複使用的Fragment,你可以用一個Activity去關聯他們,並用程式邏輯連接它們以實現整體複合UI。
通常你會想要一個fragment與另一個資料傳遞,例如使用者事件來更新內容。所有的fragment到fragment的通信都是透過Activity關聯來進行的。兩個Fragment不應該直接資料傳遞。
....................
因此,從上述我們知道為了達到Fragment能重複使用,Google官網建議在Fragment程式寫法採用上述的第二種方式。(詳見Communicating with Other Fragments網頁說明)。

在Communicating with Other Fragments官網中的畫面右上方可以看到 Download the sample ,我們可以下載到檔名為FragmentBasics.zip的官網範例,而這篇中告訴我們為達到Fragment的資料傳遞必須:
1.Define an Interface
2.Implement the Interface
3.Deliver a Message to a Fragment

在定義接口(Define an Interface)部分,可以參考範例中HeadlinesFragment.java,我們可以從 onAttach()中看到定義了mCallback然後在程式上方定義了OnHeadlineSelectedListener接口方法作為與Activity間的資料傳遞使用。
然後使用onListItemClick()將事件傳送給Activity。

為了在MainActivity獲得上述的事件,必須實現接口(Implement the Interface),我們可以從MainActivity.java中看到implements HeadlinesFragment.OnHeadlineSelectedListener{.....
然後在onArticleSelected()中進行所接收的事件處理以及顯示文章。

至於Deliver a Message to a Fragment部分,在Fragment中可以透過getActivity()方法來取得所在的Activity元件中的相關資訊。例如從Fragment中取得Activity的ListView可以使用下列方法:
View listView =getActivity().findViewById(R.id.list);
而Activity要使用Fragment元件則是使用getFragmentManager()方法:
ExampleFragment fragment =(ExampleFragment)getFragmentManager().findFragmentById(R.id.example_fragment);
如果遇到沒有UI的Fragment則透過findFragmentByTag()來實現。

以上,部分如果看不懂的話詳見Communicating with Other Fragments官網中說明,並且下載範例實作一次就會明白了。
實作FragmentBasics.zip這個範例,我們先解壓縮然後打開Eclipse,選擇 New-->Android Project from Existing Code 
接著選擇解壓縮後的目錄名稱FragmentBasics,這時候Projects會有一項目被選擇,如果要將程式碼拷貝到workspace時記得在下面的Copy projects into workspace前打勾。

然後選擇Finish就完成匯入程式了。


範例結果:
平板結果:

手機結果:


上述Eclipse環境:
Win 7 Sp1
Java version 1.6.0_35
Eclipse 3.7.2
ADT 20.0.1
ASUS Nexus 7 平板 (4.1.2)
HTC Sensation 手機 (4.0.3)


參考:
1.Communicating with Other Fragments
http://developer.android.com/training/basics/fragments/communicating.html

2.getActivity ()
http://developer.android.com/reference/android/app/Fragment.html#getActivity()

3.FragmentManager
http://developer.android.com/reference/android/app/FragmentManager.html




==============延伸閱讀=====================

1.第一支Android Fragment程式--HelloFragment
http://cheng-min-i-taiwan.blogspot.tw/2012/04/android-fragment-hellofragment.html

2.Android Fragments 的生命週期
http://cheng-min-i-taiwan.blogspot.tw/2012/12/android-fragments.html

3.Fragment間的資料傳遞
http://cheng-min-i-taiwan.blogspot.tw/2013/01/fragment.html

4.Fragment與Activity間的資料傳遞
http://cheng-min-i-taiwan.blogspot.tw/2013/02/fragmentactivity.html

5.Fragment子類別之ListFragment
http://cheng-min-i-taiwan.blogspot.tw/2013/02/fragmentlistfragment.html

6.Fragment子類別之DialogFragment
http://cheng-min-i-taiwan.blogspot.tw/2013/02/fragmentdialogfragment.html

7.Fragment子類別之PreferenceFragment
http://www.cheng-min-i-taiwan.blogspot.tw/2013/02/fragmentpreferencefragment.html

8.Fragment子類別之WebViewFragment
http://cheng-min-i-taiwan.blogspot.tw/2013/02/fragmentwebviewfragment.html

沒有留言:

張貼留言