一、Fragment的状态和回调
1. 运行状态
当一个碎片是可见的,并且它所关联的活动正处于运行状态时,该碎片也处于运行状态。
2. 暂停状态
当一个活动进入暂停状态时(由于另一个未占满屏幕的活动被添加到了栈顶),与它相关联的可见碎片就会进入到暂停状态。
3. 停止状态
当一个活动进入停止状态时,与它相关联的碎片就会进入到停止状态。或者通过调用 FragmentTransaction 的 remove()、replace()方法将碎片从活动中移除,但有在事务提交之前调用 addToBackStack()方法,这时的碎片也会进入到停止状态。总的来说,进入停止状态的碎片对用户来说是完全不可见的,有可能会被系统回收。
4. 销毁状态
碎片总是依附于活动而存在的,因此当活动被销毁时,与它相关联的碎片就会进入到销毁状态。或者通过调用 FragmentTransaction 的 remove()、replace()方法将碎片从活动中移除,但在事务提交之前并没有调用 addToBackStack()方法,这时的碎片也会进入到销毁状态。
相比Activity,Fragment 类中也提供了一系列的回调方法,以覆盖碎片生命周期的每个环节。其中,活动中有的回调方法,碎片
中几乎都有,不过碎片还提供了一些附加的回调方法,那我们就重点来看下这几个回调。
1. onAttach()
当碎片和活动建立关联的时候调用。
2. onCreateView()
为碎片创建视图(加载布局)时调用。
3. onActivityCreated()
确保与碎片相关联的活动一定已经创建完毕的时候调用。
4. onDestroyView()
当与碎片关联的视图被移除的时候调用。
5. onDetach()
当碎片和活动解除关联的时候调用。
二、Fragment的生命周期
为了更好地进行理解,我们修改上一篇中的实例来实践一下。
修改 RightFragment 中的代码,如下所示:
public class RightFragment extends Fragment {
public static final String TAG = "RightFragment";
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.d(TAG, "onAttach");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
View view = inflater.inflate(R.layout.right_fragment, container, false);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(TAG, "onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart");
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
@Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.d(TAG, "onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
@Override
public void onDetach() {
super.onDetach();
Log.d(TAG, "onDetach");
}
}
我们在 RightFragment 中的每一个回调方法里都加入了打印日志的代码,然后运行程序,这时观察 LogCat 中的打印信息,如下图所示:(注意:这里需要自己设置好LogCat的过滤器)
可以看到,当 RightFragment 第一次被加载到屏幕上时,会依次执行 onAttach()、onCreate()、onCreateView()、onActivityCreated()、onStart()和 onResume()方法。然后点击LeftFragment 中的按钮,此时打印信息如下图所示。
由于 AnotherRightFragment 替换了 RightFragment,此时的 RightFragment 进入了停止状态,因此 onPause()、onStop()和 onDestroyView()方法会得到执行。当然如果在替换的时候没有调用 addToBackStack()方法,此时的 RightFragment 就会进入销毁状态,onDestroy()和onDetach()方法就会得到执行。
接着按下 Back 键,RightFragment 会重新回到屏幕,打印信息如下图所示。
由于 RightFragment 重新回到了运行状态,因此 onActivityCreated()、 onStart()和onResume()方法会得到执行。注意此时 onCreate()和 onCreateView()方法并不会执行,因为我们借助了 addToBackStack()方法使得 RightFragment 和它的视图并没有销毁。再次按下 Back 键退出程序,打印信息如下图所示。
依次会执行 onPause()、onStop()、onDestroyView()、onDestroy()和 onDetach()方法,最终将活动和碎片一起销毁。
另外值得一提的是,在碎片中你也是可以通过 onSaveInstanceState()方法来保存数据的,因为进入停止状态的碎片有可能在系统内存不足的时候被回收。保存下来的数据在onCreate()、onCreateView()和 onActivityCreated()这三个方法中你都可以重新得到,它们都含有一个 Bundle 类型的 savedInstanceState 参数。