編輯:關於Android編程
Fragment是Activity中用戶界面的一個行為或者是一部分。主要是支持在大屏幕上動態和更為靈活的去組合或是交換UI組件,通過將activity的布局分割成若干個fragment,可以在運行時編輯activity的呈現,並且那些變化會被保存在由activity管理的後台棧裡面。
Fragment必須總是被嵌入到一個activity之中,並且fragment的生命周期直接受其宿主activity的生命周期的影響。你可以認為fragment是activity的一個模塊零件,它有自己的生命周期,接收它自己的輸入事件,並且可以在activity運行時添加或者刪除。
應該將每一個fragment設計為模塊化的和可復用化的activity組件。也就是說,你可以在多個activity中引用同一個fragment,因為fragment定義了它自己的布局,並且使用它本身生命周期回調的行為。
先看fragment生命周期圖:
fragment所生存的activity生命周期直接影響著fragment的生命周期,由此針對activity的每一個生命周期回調都會引發一個fragment類似的回調。例如,當activity接收到onPause()時,這個activity之中的每個fragment都會接收到onPause()。
這有Activity的詳細說明
Fragment有一些額外的生命周期回調方法(創建和銷毀fragment界面).
onAttach()
當fragment被綁定到activity時調用(Activity會被傳入)。
onCreateView()
將本身的布局構建到activity中去(fragment作為activity界面的一部分)
onActivityCreated()
當activity的onCreate()函數返回時被調用。
onDestroyView()
當與fragment關聯的視圖體系正被移除時被調用。
onDetach()
當fragment正與activity解除關聯時被調用。
當activity接收到它的onCreate()回調時,activity之中的fragment接收到onActivityCreated()回調。
一旦activity處於resumed狀態,則可以在activity中自由的添加或者移除fragment。因此,只有當activity處於resumed狀態時,fragment的生命周期才可以獨立變化。
fragment會在 activity離開恢復狀態時 再一次被activity推入它的生命周期中。
管理fragment生命周期與管理activity生命周期很相像。像activity一樣,fragment也有三種狀態:
Resumed
fragment在運行中的activity可見。
Paused
另一個activity處於前台且得到焦點,但是這個fragment所在的activity仍然可見(前台activity部分透明,或者沒有覆蓋全屏)。
Stopped
fragment不可見。要麼宿主activity已經停止,要麼fragment已經從activity上移除,但已被添加到後台棧中。一個停止的fragment仍然活著(所有狀態和成員信息仍然由系統保留著)。但是,它對用戶來講已經不再可見,並且如果activity被殺掉,它也將被殺掉。
如果activity的進程被殺掉了,在activity被重新創建時,你需要恢復fragment狀態。可以執行fragment的onSaveInstanceState()來保存狀態(注意在fragment是在onCreate(),onCreateView(),或onActvityCreate()中進行恢復)。
在生命周期方面,activity與fragment之間一個很重要的不同,就是在各自的後台棧中是如何存儲的。
當activity停止時,默認情況下activity被安置在由系統管理的activity後台棧中;
fragment僅當在一個事務被移除時,通過顯式調用addToBackStack()請求保存的實例,該fragment才被置於由宿主activity管理的後台棧。
要創建一個fragment,必須創建一個fragment的子類。一般情況下,我們至少需要實現以下幾個fragment生命周期方法:
onCreate()
在創建fragment時系統會調用此方法。在實現代碼中,你可以初始化想要在fragment中保持的那些必要組件,當fragment處於暫停或者停止狀態之後可重新啟用它們。
onCreateView()
在第一次為fragment繪制用戶界面時系統會調用此方法。為fragment繪制用戶界面,這個函數必須要返回所繪出的fragment的根View。如果fragment沒有用戶界面可以返回空。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment, container, false);
}
inflate()函數需要以下三個參數:
①要inflate的布局的資源ID。
②被inflate的布局的父ViewGroup。
③一個布爾值,表明在inflate期間被infalte的布局是否應該附上ViewGroup(第二個參數container)。(在這個例子中傳入的是false,因為系統已經將被inflate的布局插入到容器中(container)——傳入true會在最終的布局裡創建一個多余的ViewGroup。)
onPause()
系統回調用該函數作為用戶離開fragment的第一個預兆(盡管這並不總意味著fragment被銷毀)。在當前用戶會話結束之前,通常要在這裡提交任何應該持久化的變化(因為用戶可能不再返回)。
可以通過在activity布局文件中聲明fragment,用fragment標簽把fragment插入到activity的布局中,或者是用應用程序源碼將它添加到一個存在的ViewGroup中。
但fragment並不是一個定要作為activity布局的一部分,fragment也可以為activity隱身工作。
可以像為view一樣為fragment指定布局屬性。例如:
fragment標簽中的android:name 屬性指定了布局中實例化的Fragment類。
當系統創建activity布局時,它實例化了布局文件中指定的每一個fragment,並為它們調用onCreateView()函數,以獲取每一個fragment的布局。系統直接在元素的位置插入fragment返回的View。
注意:每個fragment都需要一個唯一的標識,如果重啟activity,系統可用來恢復fragment(並且可用來捕捉fragment的事務處理,例如移除)。為fragment提供ID有三種方法:
用android:id屬性提供一個唯一的標識。
用android:tag屬性提供一個唯一的字符串。
如果上述兩個屬性都沒有,系統會使用其容器視圖(view)的ID。
在activity運行的任何時候,你都可以將fragment添加到activity布局中。
要管理activity中的fragment,可以使用FragmentManager。可以通過在activity中調用getFragmentManager()獲得。使用FragmentManager 可以做如下事情,包括:
使用findFragmentById()(用於在activity布局中提供有界面的fragment)或者findFragmentByTag()獲取activity中存在的fragment(用於有界面或者沒有界面的fragment)。
使用popBackStack()(模仿用戶的BACK命令)從後台棧彈出fragment。
使用addOnBackStackChangedListener()注冊一個監聽後台棧變化的監聽器。
在Android中,對Fragment的事務操作都是通過FragmentTransaction來執行。操作大致可以分為兩類:
顯示:add() replace() show() attach()
隱藏:remove() hide() detach()
說明:
調用show() & hide()方法時,Fragment的生命周期方法並不會被執行,僅僅是Fragment的View被顯示或者?隱藏。執行replace()時(至少兩個Fragment),會執行第二個Fragment的onAttach()方法、執行第一個Fragment的onPause()-onDetach()方法,同時containerView會detach第一個Fragment的View。
add()方法執行onAttach()-onResume()的生命周期,相對的remove()就是執行完成剩下的onPause()-onDetach()周期。
可以像下面這樣從Activity中取得FragmentTransaction的實例:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
可以用add()函數添加fragment,並指定要添加的fragment以及要將其插入到哪個視圖(view)之中(注意commit事務):
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
也可以使用fragment為activity提供後台動作,卻不呈現多余的用戶界面。
想要添加沒有界面的fragment ,可以使用add(Fragment, String)(為fragment提供一個唯一的字符串“tag”,而不是視圖(view)ID)。這樣添加了fragment,但是,因為還沒有關聯到activity布局中的視圖(view) ,收不到onCreateView()的調用。所以不需要實現這個方法。
對於無界面fragment,字符串標簽是唯一識別它的方法。如果之後想從activity中取到fragment,需要使用findFragmentByTag()。
在調用commit()之前,可以將事務添加到fragment事務後台棧中(通過調用addToBackStatck())。這個後台棧由activity管理,並且允許用戶通過按BACK鍵回退到前一個fragment狀態。
下面的代碼中一個fragment代替另一個fragment,並且將之前的fragment狀態保留在後台棧中:
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
注意:
如果添加多個變更事務(例如另一個add()或者remove())並調用addToBackStack(),那麼在調用commit()之前的所有應用的變更被作為一個單獨的事務添加到後台棧中,並且BACK鍵可以將它們一起回退。
當移除一個fragment時,如果調用了addToBackStack(),那麼之後fragment會被停止,如果用戶回退,它將被恢復過來。
調用commit()並不立刻執行事務,相反,而是采取預約方式,一旦activity的界面線程(主線程)准備好便可運行起來。然而,如果有必要的話,你可以從界面線程調用executePendingTransations()立即執行由commit()提交的事務。
只能在activity保存狀態(當用戶離開activity時)之前用commit()提交事務。如果你嘗試在那時之後提交,會拋出一個異常。這是因為如果activity需要被恢復,提交後的狀態會被丟失。對於這類丟失提交的情況,可使用commitAllowingStateLoss()
Activity中已經有了該Fragment的引用,直接通過該引用進行交互。
-如果沒引用可以通過調用fragment的函數findFragmentById()或者findFragmentByTag(),從FragmentManager中獲取Fragment的索引,例如:
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
在Fragment中可以通過getActivity得到當前綁定的Activity的實例。
創建activity事件回調函數,在fragment內部定義一個回調接口,宿主activity來實現它。
本文實例為大家分享了Android圓形菜單的使用方法,供大家參考,具體內容如下MainActivity.java代碼:package siso.handlerdemo;i
本文承接,Android 開發第五彈:簡易時鐘(鬧鐘) 和 Android 開發第六彈:簡易時鐘(計時器),這一部分是關於秒表的。布局同樣是新建一個類(StopWatch
在Android NDK開發中,有兩個重要的文件:Android.mk和Application.mk,各盡其責,指導編譯器如何編譯程序,並決定編譯結果是什麼。本文將詳細說
從Android2.3開始支持NFC。不過NFC應用只能在Android手機(或平板電腦)上測試和開發,而且Android手機還必須有NFC芯 片。而且如果測試NFC傳輸