標籤:android fragment fragmentmanager fragmenttransaction 詳解
Android實習劄記(4)---Fragment(片段)基本概念解析
轉載請註明出處:coder-pig
Fragment相信大家都不會陌生吧,側滑啦,抽屜效果啦,DialogFragment啊等等,一堆地方都會
用到Fragment,對於Fragment的基本概念在前面的文章中其實已經給出的了,這裡回顧一遍,
溫故而知新嘛,同時結合Google官方的api進行複習!
1)什麼是Fragment以及它的生命週期:
核心要點:
1)3.0版本後引入,即minSdk要大於11
2)Fragment需要嵌套在Activity中使用,當然也可以嵌套到另外一個Fragment中,但這個被嵌套
的Fragment也是需要嵌套在Activity中的,間接地說,Fragment還是需要嵌套在Activity中!!受寄主
Activity的生命週期影響,當然他也有自己的生命週期!另外不建議在Fragment裡面嵌套Fragment
因為嵌套在裡面的Fragment生命週期不可控!!!
3)官方文檔說建立Fragment時至少需要實現三個方法:onCreate( ),onCreateView( ),OnPause( );
不過貌似唯寫一個onCreateView也是可以的...
4)Fragment的生命週期和Activity有點類似:三種狀態:
Resumed:在允許中的Fragment可見 Paused:所在Activity可見,但是得不到焦點
Stoped:
①調用addToBackStack(),Fragment被添加到Bcak棧
②該Activity轉向後台,或者該Fragment被替換/刪除
ps:停止狀態的fragment仍然活著(所有狀態和成員資訊被系統保持著),然而,它對使用者
不再可見,並且如果activity被幹掉,他也會被幹掉.
5)Fragment的子類有:
對話方塊:DialogFragment 列表:ListFragment
選項設定:PreferenceFragment WebView介面:WebViewFragment
2)如何去建立一個Fragment?
①靜態添加Fragment
step 1:定義Fragment的布局,就是fragment顯示內容的
step 2:自訂一個Fragment類,需要繼承Fragment或者他的子類,重寫onCreateView()方法
在該方法中調用:inflater.inflate()方法載入Fragment的布局檔案,接著返回載入的view對象
public class Fragmentone extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment1, container,false);return view;}}
參數依次是:要載入的fragment布局;載入的fragment所在的父ViewGroup;而第三個參數則是:
是否將父ViewGroup添加到布局檔案的根視圖上,但是這樣可能會產生一個多餘的ViewGroup
對象;這裡不理解的話就算了,寫false就可以了
另外inflate方法還有其他的形式,一種典型的就是直接inflate(要顯示布局,null),
如果使用這種的話:item布局中的根視圖的layout_XX屬性會被忽略掉,然後設定成預設的包裹
內容方式,所以還是建議使用三個參數的inflate()吧!詳細緣由可參考:
http://www.2cto.com/kf/201407/313054.html
step 3:在需要載入Fragment的Activity對應的布局檔案中添加fragment的標籤,
記住,name屬性是全限定類名哦,就是要包含Fragment的包名,如:
<fragment android:id="@+id/fragment1" android:name="com.jay.example.fragmentdemo.Fragmentone" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" />
step 4:Activity在onCreate( )方法中調用setContentView()載入布局檔案即可!
②動態添加Fragment
step 1:調用getFragmentManager獲得FragmentManager對象fm
step 2.fm調用beginTransaction( )方法獲得Fragment事務對象bt
step 3:bt調用add( )添加或者relpace( )替換Fragment,參數都是一樣的
第一個參數是要傳入的容器,第二個參數是Fragment對象
step 4:最後還需要調用bt.commit( )提交事務,除了add和replace方法外
還有個remove移除Fragment的方法,同樣也是需要commit的!
局部代碼:
Fragment1 f1 = new Fragment1();getFragmentManager().beginTransaction().replace(R.id.LinearLayout1, f1).commit();
ps:這裡的代碼是app包下的使用fragment,所以匯入的與Fragment有關的包都要是app哦!!!
另外為了低版本相容也可以用v4包,改點東西而已,詳細解析請見:
Fragment用app包還是v4包詳解
3)Fragment與Activity的互動①組件擷取:
Fragment獲得Activity中的組件:
getActivity().findViewById(R.id.list)
Activity獲得Fragment中的組件(根據id和tag都可以):
getFragmentManager.findFragmentByid(R.id.fragment1);
②資料傳遞
1.Activit傳遞資料給Fragment:
在Activity中建立Bundle資料包,調用Fragment執行個體的setArguments(bundle)
從而將Bundle資料包傳給Fragment,然後Fragment中調用getArguments獲得
Bundle對象,然後進行解析就可以了
2.Fragment傳遞資料給Activity
在Fragment中定義一個內部回調介面,再讓包含該Fragment的Activity實現該回調介面,
Fragment就可以通過回調介面傳資料了,回調,相信很多人都知道是什麼玩意,但是
寫不出來啊,網上的一百度"fragment傳資料給Activity",全是李剛老師的那個代碼,真心無語
算了,這裡就寫下局部代碼吧,相信讀者一看就懂的了:
step 1:定義一個回調介面:(Fragment中)
/*介面*/ public interface CallBack{ /*定義一個擷取資訊的方法*/ public void getResult(String result); }
step 2:介面回調(fragment中)
/*介面回調*/ public void getData(CallBack callBack){ /*擷取文字框的資訊,當然你也可以傳其他類型的參數,看需求咯*/ String msg = editText.getText().toString(); callBack.getResult(msg); }
step 3:使用介面回調方法讀資料(Activity中)
/* 使用介面回調的方法擷取資料 */ leftFragment.getData(new CallBack() { @Override public void getResult(String result) { /*列印資訊*/ Toast.makeText(MainActivity.this, "-->>" + result, 1).show(); }});
總結來說,就是
->在Fragment定義一個介面,介面中定義抽象方法,你要傳什麼類型的資料
參數就設定為什麼類型;
->接著還有寫一個調用介面中的抽象方法,把要傳遞的資料傳過去
->再接著就是Activity了,調用Fragment提供的那個方法,然後重寫抽象方法的時候進行資料
的讀取就可以了!!!
3.Fragment與Fragment傳資料
其實這很簡單,找到要接受資料的fragment對象,直接調用setArguments傳資料進去就可以了
通常的話是replace時,即fragment跳轉的時候傳資料的,那麼只需要在初始化要跳轉的Fragment
後調用他的setArguments方法傳入資料即可!
大概代碼如下:
FragmentManager fManager = getSupportFragmentManager( );FragmentTransaction fTransaction = fManager.beginTransaction();Fragmentthree t1 = new Fragmentthree();Fragmenttwo t2 = new Fragmenttwo();Bundle bundle = new Bundle();bundle.putString("key",id);t2.setArguments(bundle); fTransaction.add(R.id.fragmentRoot, t2, "~~~"); fTransaction.addToBackStack(t1); fTransaction.commit();
如果是兩個Fragment需要即時傳資料,而非跳轉的話,就需要先在Activity獲得f1傳過來的資料,再傳
到f2了
4)Fragment管理與Fragment事務:①管理:
Activity管理Fragment主要依靠FragmentManager可以調用findFragmentById( )擷取指定的fragment
也可以調用popBackStack( )方法彈出後台Fragment;也可以調用addToBackStack(null)加入棧
或者監聽後台棧的變化:addOnBackStackChangeListener
②事務
如果是增刪替換Fragment的話,則需要藉助FragmentTransaction對象;
同時執行Fragment的操作後,記得操作完後再使用commit( )方法提交事務哦!
5)最後說幾句:
相信上面的生命週期圖一時半會你也是記不住的,最後就初略地講下大概流程吧:
①Activity載入Fragment的時候,依次調用下面的方法:
onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume;
②當我們弄出一個懸浮的對話方塊風格的Activity,或者其他,就是讓Fragment所在的Activity可見,但不獲得焦點
onPause
③當對話方塊關閉,Activity又獲得了焦點:
onResume
④當我們替換Fragment,並調用addToBackStack()將他添加到Back棧中
onPause -> onStop -> onDestoryView
注意,此時的Fragment還沒有被銷毀哦!!!
⑤當我們按下鍵盤的回退鍵,Fragment會再次顯示出來:
onCreateView -> onActivityCreated -> onStart -> onResume;
⑥如果我們替換後,在事務commit之前沒有調用addToBackStack()方法將
Fragment添加到back棧中的話;又或者退出了Activity的話,那麼Fragment將會被完全結束,
Fragment會進入銷毀狀態
onPause -> onStop -> onDestoryView -> onDestory -> onDetach
Android實習劄記(4)---Fragment(片段)基本概念解析