1. 程式人生 > >Fragment生命周期以及使用時的小問題

Fragment生命周期以及使用時的小問題

tex 布局 橫豎屏切換 onstop tap over .get public edit

前言-

昨天在寫UI的時候用到了FRAGMENT,發現自己對此還不是非常了解,借此機會記錄一下

Fragment的生命周期-

官方生命周期圖:

技術分享圖片

Fragment每個生命周期方法的意義、作用-

onViewStateRestored(Bundle):告訴片段,它的視圖層次結構的所有保存狀態都已恢復。

setUserVisibleHint():設置Fragment可見或者不可見時會調用此方法。在該方法裏面可以通過調用getUserVisibleHint()獲得Fragment的狀態是可見還是不可見的,如果可見則進行懶加載操作。onAttach():執行該方法時,Fragment與Activity已經完成綁定,該方法有一個Activity類型的參數,代表綁定的Activity,這時候你可以執行諸如mActivity = activity的操作。


onCreate():初始化Fragment。可通過參數savedInstanceState獲取之前保存的值。


onCreateView():初始化Fragment的布局。加載布局和findViewById的操作通常在此函數內完成,但是不建議執行耗時的操作,比如讀取數據庫數據列表。


onActivityCreated():執行該方法時,與Fragment綁定的Activity的onCreate方法已經執行完成並返回,在該方法內可以進行與Activity交互的UI操作,所以在該方法之前Activity的onCreate方法並未執行完成,如果提前進行交互操作,會引發空指針異常。


onStart

():執行該方法時,Fragment由不可見變為可見狀態。


onResume():執行該方法時,Fragment處於活動狀態,用戶可與之交互。


onPause():執行該方法時,Fragment處於暫停狀態,但依然可見,用戶不能與之交互。


onSaveInstanceState():保存當前Fragment的狀態。該方法會自動保存Fragment的狀態,比如EditText鍵入的文本,即使Fragment被回收又重新創建,一樣能恢復EditText之前鍵入的文本。


onStop():執行該方法時,Fragment完全不可見。


onDestroyView():銷毀與Fragment有關的視圖,但未與Activity解除綁定,依然可以通過onCreateView方法重新創建視圖。通常在ViewPager+Fragment的方式下會調用此方法。


onDestroy():銷毀Fragment。通常按Back鍵退出或者Fragment被回收時調用此方法。


onDetach():解除與Activity的綁定。在onDestroy方法之後調用。

Fragment生命周期執行流程-

  • Fragment創建

  setUserVisibleHint()->onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume();Fragment變為不可見狀態(鎖屏、回到桌面、被Activity完全覆蓋):onPause()->onSaveInstanceState()->onStop();

  • Fragment變為部分可見狀態(打開Dialog樣式的Activity)

  onPause()->onSaveInstanceState();

  • Fragment由不可見變為活動狀態

  onStart()->OnResume();

  • Fragment由部分可見變為活動狀態

  onResume();

  • 退出應用

  onPause()->onStop()->onDestroyView()->onDestroy()->onDetach()(註意退出不會調用onSaveInstanceState方法,因為是人為退出,沒有必要再保存數據);

  • Fragment被回收又重新創建:

  被回收執行onPause()->onSaveInstanceState()->onStop()->onDestroyView()->onDestroy()->onDetach(),

  重新創建執行onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()->setUserVisibleHint();

  • 橫豎屏切換-

  與Fragment被回收又重新創建一樣。

  摘自法捷耶夫大佬的文章https://www.cnblogs.com/fajieyefu/p/6092465.html

實戰中遇到的一些小問題-

Fragment中獲取上下文Context對象

getActivity();  //獲取包含該fragment的活動(activity)的上下文

通過上面的生命周期我們知道fragment在OnAttach後才會獲取Activity,所以這個方法需要寫在onAttach()或者在其以後生命周期方法中

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        context=this.getActivity();
    }

getContext();  //獲取該fragment上下文 只查看當前運行的活動的上下文。(Fragment是嵌在Activity的話,感覺這個和Activity的context是一樣的)

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view=inflater.inflate(R.layout.fragment_liebie,container,false);
    context=view.getContext();
}

getApplicationContext() ;  //生命周期是整個應用,應用摧毀它才摧毀。而Activity.this的context 拿到的是當前Activity的Context,而getApplicationContext()拿到的是Application的Context。

1.this.getActivity()

  • 優點:直接調用就能獲取
  • 缺點:Fragment很容易被銷毀,調用getActivity()方法會報空指針錯誤(註意:並不是getActivity()返回值為null,而是this.getActivity()中的this,也就是Fragment自己是null,因為它已經被銷毀了)

2.獲取Application對象

  • 優點:不會遇到類似this.getActivity()的空指針問題
  • 缺點:某些情況下的Context必須是Activity,特別是實例化Dialog等需要依附於一個Activity的可視化的對象時傳參必須是Activity對象(Toast是Android的一種通知機制,不需要依附於Activity

getActivity().getApplicationContext();//通過包含該fragment的活動(activity)獲取整個應用的上下文

getContext().getApplicationContext();//通過該fragment獲取整個應用的上下文Fragment中findViewById

這四種方式效果相同

Fragment中的findViewById

findViewById方法卻只能被用在Activity類中,但是如果想要在fragment中使用的話就需要view了

View view = inflater.inflate(R.layout.view, container, false);
//兩種皆可
TextView tx=view.findViewById(R.id.id_view);
//TextView tx=getView().findViewById(R.id.id_view);

Fragment生命周期以及使用時的小問題