Fragment的生命周期
一、镇楼图
依次进行介绍:
Fragment每个生命周期方法的意义、作用(注意红色的不是生命周期方法):
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被回收又重新创建一样。
二、验证程序
我们采用ViewPager+Fragment的方式来验证:
首先,这么定义MainActivity
1 package com.example.yanyongjun.fragmentdemo; 2 3 import android.support.design.widget.TabLayout; 4 import android.support.v4.app.Fragment; 5 import android.support.v4.app.FragmentPagerAdapter; 6 import android.support.v4.view.ViewPager; 7 import android.support.v7.app.AppCompatActivity; 8 import android.os.Bundle; 9 10 import java.util.ArrayList; 11 import java.util.Date; 12 13 public class MainActivity extends AppCompatActivity { 14 15 ArrayList<Fragment> mFragList = new ArrayList<>(); 16 FragmentPagerAdapter mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) { 17 @Override 18 public Fragment getItem(int i) { 19 return mFragList.get(i); 20 } 21 22 @Override 23 public int getCount() { 24 return mFragList.size(); 25 } 26 }; 27 28 29 @Override 30 protected void onCreate(Bundle savedInstanceState) { 31 super.onCreate(savedInstanceState); 32 setContentView(R.layout.activity_main); 33 initViewPager(); 34 initTabLayout(); 35 } 36 37 private void initTabLayout(){ 38 TabLayout tabLayout = findViewById(R.id.tablayout); 39 ViewPager viewPager = findViewById(R.id.view_pager); 40 tabLayout.setupWithViewPager(viewPager); 41 tabLayout.setTabMode(TabLayout.MODE_FIXED); 42 tabLayout.getTabAt(0).setText("0"); 43 tabLayout.getTabAt(1).setText("1"); 44 tabLayout.getTabAt(2).setText("2"); 45 tabLayout.getTabAt(3).setText("3"); 46 } 47 48 private void initViewPager(){ 49 mFragList.add(new MyFragment().setTag("0")); 50 mFragList.add(new MyFragment().setTag("1")); 51 mFragList.add(new MyFragment().setTag("2")); 52 mFragList.add(new MyFragment().setTag("3")); 53 54 ViewPager viewPager = findViewById(R.id.view_pager); 55 viewPager.setAdapter(mAdapter); 56 } 57 }
然后我们的Fragment如下定义,在几乎所有的生命周期类方法中都加上日志:
1 package com.example.yanyongjun.fragmentdemo; 2 3 import android.content.Context; 4 import android.os.Bundle; 5 import android.support.annotation.NonNull; 6 import android.support.annotation.Nullable; 7 import android.support.v4.app.Fragment; 8 import android.util.Log; 9 import android.view.LayoutInflater; 10 import android.view.View; 11 import android.view.ViewGroup; 12 import android.widget.TextView; 13 14 public class MyFragment extends Fragment { 15 private String TAG = "MyFragment-"; 16 17 public MyFragment setTag(String tag) { 18 TAG = TAG + tag + "-"; 19 return this; 20 } 21 22 @Override 23 public void onAttach(Context context) { 24 super.onAttach(context); 25 Log.e(TAG, TAG + "onAttach"); 26 } 27 28 @Override 29 public void onCreate(@Nullable Bundle savedInstanceState) { 30 super.onCreate(savedInstanceState); 31 Log.e(TAG, TAG + "onCreate"); 32 } 33 34 @Nullable 35 @Override 36 public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 37 Log.e(TAG, TAG + "onCreateView"); 38 View v = inflater.inflate(R.layout.fragment_my, null); 39 TextView lab = v.findViewById(R.id.lab); 40 lab.setText(TAG); 41 return v; 42 } 43 44 @Override 45 public void onStart() { 46 super.onStart(); 47 Log.e(TAG, TAG + "onStart"); 48 } 49 50 @Override 51 public void onStop() { 52 super.onStop(); 53 Log.e(TAG, TAG + "onStop"); 54 } 55 56 @Override 57 public void setUserVisibleHint(boolean isVisibleToUser) { 58 super.setUserVisibleHint(isVisibleToUser); 59 Log.e(TAG, TAG + "setUserVisibleHint" + isVisibleToUser); 60 } 61 62 @Override 63 public void onResume() { 64 super.onResume(); 65 Log.e(TAG, TAG + "onResume"); 66 } 67 68 @Override 69 public void onDestroyView() { 70 super.onDestroyView(); 71 Log.e(TAG, TAG + "onDestory"); 72 } 73 74 @Override 75 public void onDetach() { 76 super.onDetach(); 77 Log.e(TAG, TAG + "onDetach"); 78 } 79 80 @Override 81 public void onDestroy() { 82 super.onDestroy(); 83 Log.e(TAG, TAG + "onDestory"); 84 } 85 86 @Override 87 public void onPause() { 88 super.onPause(); 89 Log.e(TAG, TAG + "onPause"); 90 } 91 92 @Override 93 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 94 super.onViewCreated(view, savedInstanceState); 95 Log.e(TAG, TAG + "onViewCreated"); 96 } 97 98 @Override 99 public void onActivityCreated(@Nullable Bundle savedInstanceState) { 100 super.onActivityCreated(savedInstanceState); 101 Log.e(TAG, TAG + "onActivityCreated"); 102 } 103 }
当刚打开应用程序时,可以看到如下:
08-20 20:49:19.851 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-0-: MyFragment-0-setUserVisibleHintfalse
08-20 20:49:19.851 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-1-: MyFragment-1-setUserVisibleHintfalse
08-20 20:49:19.851 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-0-: MyFragment-0-setUserVisibleHinttrue //值得注意的是,setUserVisibleHint方法的执行,在onAttach执行之前
08-20 20:49:19.854 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-0-: MyFragment-0-onAttach
MyFragment-0-onCreate
08-20 20:49:19.854 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-1-: MyFragment-1-onAttach
08-20 20:49:19.855 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-1-: MyFragment-1-onCreate
08-20 20:49:19.855 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-0-: MyFragment-0-onCreateView
08-20 20:49:19.858 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-0-: MyFragment-0-onViewCreated
08-20 20:49:19.859 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-0-: MyFragment-0-onActivityCreated
MyFragment-0-onStart
MyFragment-0-onResume
08-20 20:49:19.859 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-1-: MyFragment-1-onCreateView
08-20 20:49:19.861 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-1-: MyFragment-1-onViewCreated
MyFragment-1-onActivityCreated
MyFragment-1-onStart
MyFragment-1-onResume //临近的fragment也完成了onResume操作
我们将当前页面滑动到1上
1 08-20 20:52:23.864 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-2-: MyFragment-2-setUserVisibleHintfalse 2 08-20 20:52:23.864 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-0-: MyFragment-0-setUserVisibleHintfalse //0界面被置为不可见 3 08-20 20:52:23.864 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-1-: MyFragment-1-setUserVisibleHinttrue 4 08-20 20:52:23.864 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-2-: MyFragment-2-onAttach 5 MyFragment-2-onCreate 6 08-20 20:52:23.865 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-2-: MyFragment-2-onCreateView 7 08-20 20:52:23.872 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-2-: MyFragment-2-onViewCreated 8 08-20 20:52:23.873 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-2-: MyFragment-2-onActivityCreated 9 MyFragment-2-onStart 10 08-20 20:52:23.874 31415-31415/com.example.yanyongjun.fragmentdemo E/MyFragment-2-: MyFragment-2-onResume