Fragment生命周期详解
Fragment依附Activity而存在,本文通过两个TextView切换两个Fragment来观察Activity和两个Fragment在不同操作下各执行哪些方法,从而对其生命周期有更加深刻的了解。通过打印log进行分析。
- 本文要点:
- Fragment的动态加载,和切换。
- Fragment和Activity的生命周期分析。
- 注:文中:
- 使用ButterKnife,免去findViewById。
- LogUtils.e()为个人工具类,可等视为log.e()
-
进入LifeActivity时,Fragment1显示:
-
先执行LifeActivity的 onCreate方法,再执行Fragment1的onAttach、onAttach、onCreateView、onActivityCreated方法。
- LifeActivity、Fragment1的 onStart方法 到 LifeActivity、Fragment1的 onResume方法。 可见在初始化时Activity要优先Fragment一步。
03-29 23:09:43.827 14564-14564/top.toly.www.fragment E/LifeActivity: onCreate: ====LifeActivity
03-29 23:09:43.831 14564-14564/top.toly.www.fragment E/Fragment1: onAttach: ====Fragment1
03-29 23:09:43.831 14564-14564/top.toly.www.fragment E/Fragment1: onCreate: ====Fragment1
03-29 23:09:43.831 14564-14564/top.toly.www.fragment E/Fragment1: onCreateView:====Fragment1
03-29 23:09:43.832 14564-14564/top.toly.www.fragment E/Fragment1: onActivityCreated:====Fragment1
03-29 23:09:43.832 14564-14564/top.toly.www.fragment E/LifeActivity: onStart: ====LifeActivity
03-29 23:09:43.832 14564-14564/top.toly.www.fragment E/Fragment1: onStart: ====Fragment1
03-29 23:09:43.832 14564-14564/top.toly.www.fragment E/LifeActivity: onResume: ====LifeActivity
03-29 23:09:43.832 14564-14564/top.toly.www.fragment E/Fragment1: onResume:====Fragment1
将屏幕关闭时:Fragment1、LifeActivity分别执行onPause、onStop方法。 可见在暂停时Fragment要优先Activity一步。
03-29 23:17:12.928 19745-19745/top.toly.www.fragment E/Fragment1: onPause:====Fragment1
03-29 23:17:12.928 19745-19745/top.toly.www.fragment E/LifeActivity: onPause: ====LifeActivity
03-29 23:17:12.960 19745-19745/top.toly.www.fragment E/Fragment1: onStop: ====Fragment1
03-29 23:17:12.960 19745-19745/top.toly.www.fragment E/LifeActivity: onStop: ====LifeActivity
将屏幕打开时:LifeActivity的onRestart。LifeActivity、Fragment1的onStart。LifeActivity、Fragment1的onResume
03-29 23:17:59.144 19745-19745/top.toly.www.fragment E/LifeActivity: onRestart: ====LifeActivity
03-29 23:17:59.153 19745-19745/top.toly.www.fragment E/LifeActivity: onStart: ====LifeActivity
03-29 23:17:59.153 19745-19745/top.toly.www.fragment E/Fragment1: onStart: ====Fragment1
03-29 23:17:59.154 19745-19745/top.toly.www.fragment E/LifeActivity: onResume: ====LifeActivity
03-29 23:17:59.154 19745-19745/top.toly.www.fragment E/Fragment1: onResume:====Fragment1
由Fragment1切到Fragment2时:
03-29 23:20:49.003 22825-22825/top.toly.www.fragment E/Fragment1: onPause:====Fragment1
03-29 23:20:49.005 22825-22825/top.toly.www.fragment E/Fragment1: onStop: ====Fragment1
03-29 23:20:49.005 22825-22825/top.toly.www.fragment E/Fragment1: onDestroyView: ====Fragment1
03-29 23:20:49.005 22825-22825/top.toly.www.fragment E/Fragment1: onDestroy:====Fragment1
03-29 23:20:49.006 22825-22825/top.toly.www.fragment E/Fragment1: onDetach:====Fragment1
03-29 23:20:49.006 22825-22825/top.toly.www.fragment E/Fragment2: onAttach: ====Fragment2
03-29 23:20:49.006 22825-22825/top.toly.www.fragment E/Fragment2: onCreate: ====Fragment2
03-29 23:20:49.006 22825-22825/top.toly.www.fragment E/Fragment2: onCreateView:====Fragment2
03-29 23:20:49.035 22825-22825/top.toly.www.fragment E/Fragment2: onActivityCreated:====Fragment2
03-29 23:20:49.035 22825-22825/top.toly.www.fragment E/Fragment2: onStart: ====Fragment2
03-29 23:20:49.035 22825-22825/top.toly.www.fragment E/Fragment2: onResume:====Fragment2
由Fragment2切到Fragment1时:
03-29 23:22:18.835 22825-22825/top.toly.www.fragment E/Fragment2: onPause:====Fragment2
03-29 23:22:18.835 22825-22825/top.toly.www.fragment E/Fragment2: onStop: ====Fragment2
03-29 23:22:18.835 22825-22825/top.toly.www.fragment E/Fragment2: onDestroyView: ====Fragment2
03-29 23:22:18.836 22825-22825/top.toly.www.fragment E/Fragment2: onDestroy:====Fragment2
03-29 23:22:18.836 22825-22825/top.toly.www.fragment E/Fragment2: onDetach:====Fragment2
03-29 23:22:18.837 22825-22825/top.toly.www.fragment E/Fragment1: onAttach: ====Fragment1
03-29 23:22:18.837 22825-22825/top.toly.www.fragment E/Fragment1: onCreate: ====Fragment1
03-29 23:22:18.837 22825-22825/top.toly.www.fragment E/Fragment1: onCreateView:====Fragment1
03-29 23:22:18.840 22825-22825/top.toly.www.fragment E/Fragment1: onActivityCreated:====Fragment1
03-29 23:22:18.840 22825-22825/top.toly.www.fragment E/Fragment1: onStart: ====Fragment1
03-29 23:22:18.840 22825-22825/top.toly.www.fragment E/Fragment1: onResume:====Fragment1
退出LifeActivity时:
03-29 23:11:47.792 14564-14564/top.toly.www.fragment E/Fragment1: onPause:====Fragment1
03-29 23:11:47.792 14564-14564/top.toly.www.fragment E/LifeActivity: onPause: ====LifeActivity
03-29 23:11:47.798 14564-14564/top.toly.www.fragment E/Fragment1: onStop: ====Fragment1
03-29 23:11:47.798 14564-14564/top.toly.www.fragment E/LifeActivity: onStop: ====LifeActivity
03-29 23:11:47.798 14564-14564/top.toly.www.fragment E/Fragment1: onDestroyView: ====Fragment1
03-29 23:11:47.799 14564-14564/top.toly.www.fragment E/Fragment1: onDestroy:====Fragment1
03-29 23:11:47.799 14564-14564/top.toly.www.fragment E/Fragment1: onDetach:====Fragment1
03-29 23:11:47.799 14564-14564/top.toly.www.fragment E/LifeActivity: onDestroy: ====LifeActivity
- 下面是具体代码。(源码地址:https://github.com/toly1994328/Fragment.git)
LifeActivity.java
1 package top.toly.www.fragment.life; 2 3 import android.app.FragmentManager; 4 import android.app.FragmentTransaction; 5 import android.os.Bundle; 6 import android.support.v7.app.AppCompatActivity; 7 import android.view.View; 8 import android.widget.FrameLayout; 9 import android.widget.TextView; 10 11 import butterknife.Bind; 12 import butterknife.ButterKnife; 13 import butterknife.OnClick; 14 import top.toly.www.fragment.R; 15 import utils.shortUtils.LogUtils; 16 17 public class LifeActivity extends AppCompatActivity { 18 private static final String TAG = "LifeActivity"; 19 20 @Bind(R.id.tv_title1) 21 TextView mTvTitle1; 22 @Bind(R.id.tv_title2) 23 TextView mTvTitle2; 24 @Bind(R.id.fl_life_root) 25 FrameLayout mFlLifeRoot; 26 private FragmentManager mFm; 27 private FragmentTransaction mFt; 28 29 @Override 30 protected void onCreate(Bundle savedInstanceState) { 31 super.onCreate(savedInstanceState); 32 setContentView(R.layout.activity_life); 33 LogUtils.e(TAG, "onCreate: ====LifeActivity"); 34 ButterKnife.bind(this); 35 initFragment();//初始Fragment 36 } 37 38 @Override 39 protected void onStart() { 40 super.onStart(); 41 LogUtils.e(TAG, "onStart: ====LifeActivity"); 42 } 43 44 @Override 45 protected void onResume() { 46 super.onResume(); 47 LogUtils.e(TAG, "onResume: ====LifeActivity"); 48 } 49 50 @Override 51 protected void onPause() { 52 super.onPause(); 53 LogUtils.e(TAG, "onPause: ====LifeActivity"); 54 } 55 56 @Override 57 protected void onStop() { 58 super.onStop(); 59 LogUtils.e(TAG, "onStop: ====LifeActivity"); 60 } 61 62 @Override 63 protected void onRestart() { 64 super.onRestart(); 65 LogUtils.e(TAG, "onRestart: ====LifeActivity"); 66 } 67 @Override 68 protected void onDestroy() { 69 super.onDestroy(); 70 LogUtils.e(TAG, "onDestroy: ====LifeActivity"); 71 } 72 73 private void initFragment() { 74 mFm = getFragmentManager();//1.获取FragmentManager 75 mFt = mFm.beginTransaction();//2.fm开启事务 76 mFt.add(R.id.fl_life_root, new Fragment1()); //3.动态添加 77 mFt.commit();//4.提交事务 78 } 79 80 @OnClick({R.id.tv_title1, R.id.tv_title2}) 81 public void onViewClicked(View view) { 82 mFt = mFm.beginTransaction();//2.fm开启事务 83 switch (view.getId()) { 84 case R.id.tv_title1: 85 mFlLifeRoot.removeAllViews();//先清屏 86 mFt.replace(R.id.fl_life_root, new Fragment1()); //3.动态添加 87 break; 88 case R.id.tv_title2: 89 mFlLifeRoot.removeAllViews();//先清屏 90 mFt.replace(R.id.fl_life_root, new Fragment2()); //3.动态添加 91 break; 92 } 93 mFt.commit();//4.提交事务 94 } 95 }
Fragment1.java
1 package top.toly.www.fragment.life; 2 3 4 import android.app.Fragment; 5 import android.content.Context; 6 import android.os.Bundle; 7 import android.view.LayoutInflater; 8 import android.view.View; 9 import android.view.ViewGroup; 10 11 import top.toly.www.fragment.R; 12 import utils.shortUtils.LogUtils; 13 14 /** 15 * A simple {@link Fragment} subclass. 16 */ 17 public class Fragment1 extends Fragment { 18 private static final String TAG = "Fragment1"; 19 20 public Fragment1() { 21 // Required empty public constructor 22 } 23 24 @Override 25 public void onAttach(Context context) { 26 super.onAttach(context); 27 LogUtils.e(TAG, "onAttach: ====Fragment1"); 28 } 29 30 @Override 31 public void onCreate(Bundle savedInstanceState) { 32 super.onCreate(savedInstanceState); 33 LogUtils.e(TAG, "onCreate: ====Fragment1"); 34 } 35 36 @Override 37 public View onCreateView(LayoutInflater inflater, ViewGroup container, 38 Bundle savedInstanceState) { 39 LogUtils.e(TAG, "onCreateView:====Fragment1 "); 40 return inflater.inflate(R.layout.fragment_fragment1, container, false); 41 } 42 43 @Override 44 public void onActivityCreated(Bundle savedInstanceState) { 45 super.onActivityCreated(savedInstanceState); 46 LogUtils.e(TAG, "onActivityCreated:====Fragment1 "); 47 } 48 49 @Override 50 public void onStart() { 51 super.onStart(); 52 LogUtils.e(TAG, "onStart: ====Fragment1"); 53 } 54 55 @Override 56 public void onResume() { 57 super.onResume(); 58 LogUtils.e(TAG, "onResume:====Fragment1 "); 59 } 60 61 @Override 62 public void onPause() { 63 super.onPause(); 64 LogUtils.e(TAG, "onPause:====Fragment1 "); 65 } 66 67 @Override 68 public void onStop() { 69 super.onStop(); 70 LogUtils.e(TAG, "onStop: ====Fragment1"); 71 } 72 73 @Override 74 public void onDestroyView() { 75 super.onDestroyView(); 76 LogUtils.e(TAG, "onDestroyView: ====Fragment1"); 77 } 78 79 @Override 80 public void onDestroy() { 81 super.onDestroy(); 82 LogUtils.e(TAG, "onDestroy:====Fragment1 "); 83 } 84 85 @Override 86 public void onDetach() { 87 super.onDetach(); 88 LogUtils.e(TAG, "onDetach:====Fragment1 "); 89 } 90 }
Fragment2.java
1 package top.toly.www.fragment.life; 2 3 4 import android.app.Fragment; 5 import android.content.Context; 6 import android.os.Bundle; 7 import android.view.LayoutInflater; 8 import android.view.View; 9 import android.view.ViewGroup; 10 11 import top.toly.www.fragment.R; 12 import utils.shortUtils.LogUtils; 13 14 /** 15 * A simple {@link Fragment} subclass. 16 */ 17 public class Fragment2 extends Fragment { 18 private static final String TAG = "Fragment2"; 19 20 public Fragment2() { 21 // Required empty public constructor 22 } 23 24 @Override 25 public void onAttach(Context context) { 26 super.onAttach(context); 27 LogUtils.e(TAG, "onAttach: ====Fragment2"); 28 } 29 30 @Override 31 public void onCreate(Bundle savedInstanceState) { 32 super.onCreate(savedInstanceState); 33 LogUtils.e(TAG, "onCreate: ====Fragment2"); 34 } 35 36 @Override 37 public View onCreateView(LayoutInflater inflater, ViewGroup container, 38 Bundle savedInstanceState) { 39 LogUtils.e(TAG, "onCreateView:====Fragment2 "); 40 return inflater.inflate(R.layout.fragment_fragment2, container, false); 41 } 42 43 @Override 44 public void onActivityCreated(Bundle savedInstanceState) { 45 super.onActivityCreated(savedInstanceState); 46 LogUtils.e(TAG, "onActivityCreated:====Fragment2 "); 47 } 48 49 @Override 50 public void onStart() { 51 super.onStart(); 52 LogUtils.e(TAG, "onStart: ====Fragment2"); 53 } 54 55 @Override 56 public void onResume() { 57 super.onResume(); 58 LogUtils.e(TAG, "onResume:====Fragment2 "); 59 } 60 61 @Override 62 public void onPause() { 63 super.onPause(); 64 LogUtils.e(TAG, "onPause:====Fragment2 "); 65 } 66 67 @Override 68 public void onStop() { 69 super.onStop(); 70 LogUtils.e(TAG, "onStop: ====Fragment2"); 71 } 72 73 @Override 74 public void onDestroyView() { 75 super.onDestroyView(); 76 LogUtils.e(TAG, "onDestroyView: ====Fragment2"); 77 } 78 79 @Override 80 public void onDestroy() { 81 super.onDestroy(); 82 LogUtils.e(TAG, "onDestroy:====Fragment2 "); 83 } 84 85 @Override 86 public void onDetach() { 87 super.onDetach(); 88 LogUtils.e(TAG, "onDetach:====Fragment2 "); 89 } 90 }
LifeActivity的布局文件:activity_life.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="top.toly.www.fragment.life.LifeActivity"> <LinearLayout android:id="@+id/ll_life_root" android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal"> <TextView android:id="@+id/tv_title1" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="title1" android:gravity="center"/> <TextView android:id="@+id/tv_title2" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="title2" android:gravity="center"/> </LinearLayout> <FrameLayout android:id="@+id/fl_life_root" android:layout_below="@+id/ll_life_root" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> </RelativeLayout>
Fragment1使用的布局文件:fragment_fragment1.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="top.toly.www.fragment.life.Fragment1"> <!-- TODO: Update blank fragment layout --> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center" android:textSize="24sp" android:text="@string/fragment1"/> </RelativeLayout>
Fragment2使用的布局文件:fragment_fragment2.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="top.toly.www.fragment.life.Fragment1"> <!-- TODO: Update blank fragment layout --> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center" android:textSize="24sp" android:text="@string/fragment2"/> </RelativeLayout>