談談Fragment的建構函式、重新建立(recreate)及相關
版權所有。所有權利保留。
歡迎轉載,轉載時請註明出處:
http://blog.csdn.net/xiaofei_it/article/details/45675497
本文分享一些Android Fragment使用經驗,不準備詳細介紹,只是介紹一些使用注意點,對於有一定開發經驗的朋友應該會比較有幫助。對於我理解不對的地方,希望批評指正,謝謝!
1、Fragment初始化
一定要提供預設建構函式。
不能用建構函式傳遞引數!不要寫帶引數的建構函式。引數通過下面介紹的方式傳遞。
原因:Fragment會被重新銷燬(Activity銷燬的時候它裡面的Fragment就被銷燬了,可能因為記憶體不足,手機配置發生變化,橫豎屏切換)。在重新建立的時候系統呼叫的是無參建構函式。
標準做法是:
在Fragment裡新增獲取Fragment的newInstance函式,以後獲取Fragment就使用這個函式,不要使用建構函式新建Fragment!
public static MyFragment newInstance(Bundle args) {
MyFragment f = new MyFragment();
f.setArguments(args);
return f;
}
Fragment內部在初始化的時候需要獲取外界傳遞的引數,這時候就用getArguments獲取Bundle,再從Bundle裡獲取對應的引數。Bundle在Fragment銷燬和重新建立的時候持續儲存。
比如:
private TextView mTextView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment, container, false);
initViews(view);
return view;
}
private void initViews(View view){
mTextView = view.findViewById(R.id.tv);
Bundle bundle = getArguments();
mTextView.setText(bundle == null ? "" : bundle.getString("text"));
}
Activity裡使用MyFragment時應該這樣寫:
Bundle args = new Bundle();
args.putString("text","Hello");
MyFragment f = MyFragment.newInstance(args)
2、關於getActivity()
使用所依附的Activity時應該判斷getActivity是否為空或者isAdded是否為true。
Fragment依附的Activity隨時可能被destroy掉!很多時候是在不經意間。機型適配的時候就會發現。
3、Activity引用
4、關於生命週期
通過add新增Fragment會觸發Fragment生命週期,hide和show不會觸發生命週期。
像微信那樣,一個Activity裡有四個Fragment,下面四個按鈕,點選一個按鈕顯示其中一個Fragment。這種情況下,為了優化效能,你可以這樣做:
起初只add第一個Fragment,其餘三個Fragment都不新增。點選某個標籤的時候先看對應的Fragment是否已經新增,沒有則new一個並add這個Fragment,隱藏其他所有Fragment;如果已經新增了就直接show這個Fragment,隱藏其他所有Fragment。
5、關於Fragment銷燬和重建
(1)Activity因記憶體不足、配置變化等原因被銷燬的時候,包含的Fragment也會被銷燬,無論此Fragment是否有id,系統都會呼叫Fragment的onSaveInstanceState,並且保留之前setArguments的Bundle,並且Activity的FragmentManager裡的Fragment會被記錄。
(2)由於(1)的原因,如果一個Activity裡的fragment是通過add方式新增的,那麼如果出現上述情況,就必須在Activity的add地方判斷是否應該重新新增Fragment,避免重複新增。
(3)剛剛在第1點時說到Fragment在Activity中的使用。那個地方說得還是有點問題。其實應該給每個Fragment設一個tag,在FragmentTransaction.add方法新增Fragment的時候,第三個引數使用這個tag。初始化的時候,應該先從FragmentManager裡檢視這個Fragment是否已經有,如果有就直接使用原來的,如果沒有再新建。
系統在重建Activity時會重建Fragment(呼叫Fragment的預設建構函式),並且將這些新增到FragmentManager裡,並且設定之前setArguments時使用的Bundle。此時系統回撥Fragment的onCreate(Bundle)、onActivityCreated(Bundle)、onViewStateRestored(Bundle)這類方法的時候,引數不為空。
注意:新建的Fragment和原來對應的Fragment不是同一個例項!
Activity內正確使用Fragment的程式碼如下:
FragmentManager fm = getSupportFragmentManager();
Fragment ft = fm.findFragmentByTag("MyFragment");
Bundle args = new Bundle();
args.putString("text","Hello");
MyFragment = ft == null ? MyFragment.newInstance(args) : (MyFragment)ft;
if (savedInstanceState==null){
fm.beginTransaction()
.add(R.id.fragment, ft, "MyFragment")
.commitAllowingStateLoss();
}
相關文章
- 也談箭頭函式的 this 指向問題及相關函式
- android中Fragment的建構函式AndroidFragment函式
- 溫故知新----再談建構函式 (轉)函式
- 建構函式建立物件函式物件
- 談談資料的貨幣化及相關戰略制定
- 【原創】淺談指標(八)字串相關函式(下集)指標字串函式
- 物件及函式相關物件函式
- javascript建立安全的建構函式JavaScript函式
- 談談JS中的函式劫持JS函式
- 談談函式的命名規範函式
- fragment雜談Fragment
- 關於建構函式與解構函式的分享函式
- 當我們在談論建構函式注入的時候我們在談論什麼函式
- 淺談C#的函式建立和閉包C#函式
- 談談JS中的函式節流JS函式
- 談談C++中的swap函式C++函式
- 關於string類的建構函式及部分方法函式
- 私有建構函式的物件建立例項函式物件
- Golang建立建構函式的方法詳解Golang函式
- 談談交叉熵損失函式熵函式
- 建構函式方式建立正規表示式函式
- 淺談 SAP UI5 OData 模型建構函式的輸入引數UI模型函式
- 建構函式、原型及原型鏈函式原型
- 淺談Swift中的函式式Swift函式
- 淺談eval函式函式
- 淺談生成函式函式
- 淺談尤拉函式函式
- 預設建構函式、引數化建構函式、複製建構函式、解構函式函式
- C++再議建構函式及複製建構函式深度複製C++函式
- 類的建構函式和解構函式函式
- interrupt結構體和相關函式結構體函式
- rebuild index 和 recreate index (重新建立index) 的區別RebuildIndex
- 關於scala中的主建構函式函式
- 關於建構函式的一點理解函式
- 字串的相關函式字串函式
- 【C語言】常用的字串函式及相關函式的自我實現C語言字串函式
- 談談關於 iOS 的架構以及應用iOS架構
- 新顯示卡出世,我們來談談與深度學習有關的顯示卡架構和相關技術深度學習架構