前言
一、fragment生命周期概述
与Activity类似,Fragment作为一个容器也必定有它自己的生命周期,如果能熟练掌握一个fragment从创建到销毁过程中的每一个方法,以及它们的调用时机,那么我们将可以更好的去管理一个fragment,比如我们可以根据需求,在不同的状态中做一些有用的事情,下面看一下官方给出的流程图:
下面对这11个方法做一下大致的解释。
onAttach(Activity activity)
---Called when the fragment has been associated with the activity (the Activity
is passed in here).
---当该fragment被添加到Activity时回调,该方法只会被调用一次。
onCreat(Bundle savedInstanceState)
---创建fragment时被回调。该方法只会调用一次。
onCreatView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState)
---Called to create the view hierarchy associated with the fragment.
---每次创建、绘制该fragment的View组件时回调该方法,fragment将会显示该方法的View组件。
onActivityCreated(Bundle savedInstanceState)
---Called when the activity's onCreate()
method has returned.
---当fragment所在的Activity被创建完成后调用该方法。
onStart()
---启动fragment时被回调。
onResume()
---恢复fragment时被回调,onStart()方法后一定会回调onResume()方法。
onPause()
---暂停fragment时被回调。
onStop()
---停止fragment时被回调。
onDestroyView()
---Called when the view hierarchy associated with the fragment is being removed.
---销毁该fragment所包含的View组件时调用。
onDestory()
---销毁fragment时被回调,该方法只会被调用一次。
onDetach()
---Called when the fragment is being disassociated from the activity.
---当该fragment从Activity中被删除、被替换完成时回调该方法,onDestory()方法后一定会回调onDetach()方法。该方法只会被调用一次。
其实学习生命周期最好的方法还是在程序中通过打印语句来观察每个阶段的状态和顺序,下面就通过一个简单的例子来看一下一个fragment完整的生命周期的过程。
二、一个简单的例子
Layout代码(fragment.xml):
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <TextView
- android:layout_width="match_parent"
- android:layout_height="30dp"
- android:background="#FFCC00"
- android:gravity="center"
- android:text="TextView2 in Fragment" />
- <ListView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:entries="@array/heros" >
- </ListView>
- </LinearLayout>
MyFragment代码:
- package com.example.fragmentlifecycledemo;
- import android.app.Activity;
- import android.app.Fragment;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- public class MyFragment extends Fragment {
- private final String TAG = "--MyFragment--> ";
- @Override
- public void onAttach(Activity activity) {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onAttach");
- super.onAttach(activity);
- }
- @Override
- public void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onCreate");
- super.onCreate(savedInstanceState);
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onCreateView");
- View view = inflater.inflate(R.layout.fragment, null);
- return view;
- }
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onActivityCreated");
- super.onActivityCreated(savedInstanceState);
- }
- @Override
- public void onStart() {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onStart");
- super.onStart();
- }
- @Override
- public void onResume() {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onResume");
- super.onResume();
- }
- @Override
- public void onPause() {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onPause");
- super.onPause();
- }
- @Override
- public void onStop() {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onStop");
- super.onStop();
- }
- @Override
- public void onDestroyView() {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onDestroyView");
- super.onDestroyView();
- }
- @Override
- public void onDestroy() {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onDestroy");
- super.onDestroy();
- }
- @Override
- public void onDetach() {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onDetach");
- super.onDetach();
- }
- }
可以看到上面的代码是fragment类和它所要加载的布局文件,并在fragment中声明了生命周期中的每个方法以及打印语句。fragment的布局文件很简单,只有一个TextView和一个固定内容的ListView。下面看看Activity的代码和布局文件。
Layout代码(activity_main.xml):
- <LinearLayout 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"
- android:orientation="vertical"
- tools:context="com.example.fragmentlifecycledemo.MainActivity" >
- <TextView
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:background="#FFDDFF"
- android:gravity="center"
- android:height="0dp"
- android:text="TextView1 in MainActivity" />
- <FrameLayout
- android:id="@+id/lt_frame"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="3" >
- </FrameLayout>
- </LinearLayout>
MainActivity代码:
- package com.example.fragmentlifecycledemo;
- import android.app.Activity;
- import android.app.FragmentManager;
- import android.app.FragmentTransaction;
- import android.os.Bundle;
- public class MainActivity extends Activity {
- private final String TAG = "--MainActivity---> ";
- private FragmentManager manager;
- private FragmentTransaction transaction;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- System.out.println(TAG + " onCreate");
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- manager = getFragmentManager();
- transaction = manager.beginTransaction();
- transaction.add(R.id.lt_frame, new MyFragment());
- transaction.commit();
- }
- @Override
- protected void onStart() {
- // TODO Auto-generated method stub
- System.out.println(TAG + " onStart");
- super.onStart();
- }
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- System.out.println(TAG + " onResume");
- super.onResume();
- }
- @Override
- protected void onPause() {
- // TODO Auto-generated method stub
- System.out.println(TAG + " onPause");
- super.onPause();
- }
- @Override
- protected void onStop() {
- // TODO Auto-generated method stub
- System.out.println(TAG + " onStop");
- super.onStop();
- }
- @Override
- protected void onDestroy() {
- // TODO Auto-generated method stub
- System.out.println(TAG + " onDestroy");
- super.onDestroy();
- }
- }
下面看一下运行效果和LogCat控制台的打印结果:
可以看到fragment正常被加载到了Activity的FrameLayout中了,那么现在看看LogCat:
可以看到首先是Activity被创建,紧接着fragment与Activity绑定(onAttach),然后fragment被创建(onCreat),fragment的视图被创建(onCreatView),fragment所在的Activity的onCreate()方法已经被返回(onActivityCreated),最后Actvity启动,fragment启动,Activity处于运行状态,fragment处于运行状态。
当我点返回键之后,再看一下运行效果和LogCat控制台的打印结果:
可以看到已经点击返回键退出应用了,那么现在看看LogCat:
可以看到退出的时候,首先是fragment暂停、Activity暂停,然后fragment停止、Activity停止,然后销毁fragment的视图(onDestoryView,与onCreatView相对应)、与之前绑定的Activity解除关联(onDetach,与onAttach相对应),最后是Activity的销毁。
通过上面的分析我们可以证实:
fragment的生命周期确实是伴随着Activity的生命周期变化的,并且它是依附于Activity的。先创建Activity,再创建fragment,先销毁fragment,再销毁Activity,这种层次结构的设计也是非常合理的,而且和“栈”的结构有些相似,即:“后进先出”。下面将记录fragment的另一个重要的概念,即“回退栈(back stack)”。
三、回退栈(back stack)
其实回退栈很简单,fragment的回退栈和Activity的回退栈是类似的,就是如果把一个fragment事务添加到回退栈,那么点返回按钮的时候也就可以看到上一次保存的fragment,不至于直接退出Activity。也就是通过这个方法来将fragment事务添加到回退栈的:
- transaction.addToBackStack(String name);
Layout代码(f1.xml-->二级界面的布局文件):
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/tv_textView_f1"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="0.7"
- android:background="#F7F7F7"
- android:gravity="center"
- android:text="我是HERO,我的名字是?"
- android:textSize="20sp" />
- <EditText
- android:id="@+id/et_editText_e1"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="0.15"
- android:inputType="textPersonName"
- android:hint="请输入英雄名" />
- <Button
- android:id="@+id/btn_button_b1"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="0.15"
- android:text="确定" />
- </LinearLayout>
- package com.example.fragmentlifecycledemo;
- import android.app.Activity;
- import android.app.Fragment;
- import android.app.FragmentManager;
- import android.app.FragmentTransaction;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.ListView;
- import android.widget.TextView;
- public class MyFragment extends Fragment {
- private final String TAG = "--MyFragment--> ";
- private ListView listView1;
- private FragmentManager manager;
- private FragmentTransaction transaction;
- @Override
- public void onAttach(Activity activity) {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onAttach");
- super.onAttach(activity);
- }
- @Override
- public void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onCreate");
- super.onCreate(savedInstanceState);
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onCreateView");
- View view = inflater.inflate(R.layout.fragment, container, false);
- listView1 = (ListView) view.findViewById(R.id.iv_listView_1);
- manager = getFragmentManager();
- transaction = manager.beginTransaction();
- listView1.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- // 创建二级Fragment对象
- MySubFragment msf = new MySubFragment();
- // 获取当前项的TextView
- TextView tv1 = (TextView) view;
- // 通过Bundle对象传递数据
- Bundle bundle = new Bundle();
- bundle.putCharSequence("heroName", tv1.getText().toString());
- msf.setArguments(bundle);
- // 当点击Item时将ListView替换成二级Fragment
- transaction.replace(R.id.lt_frame, msf);
- // 将事务添加到回退栈使得可以返回到上一级
- transaction.addToBackStack(null);
- transaction.commit();
- }
- });
- return view;
- }
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onActivityCreated");
- super.onActivityCreated(savedInstanceState);
- }
- @Override
- public void onStart() {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onStart");
- super.onStart();
- }
- @Override
- public void onResume() {
- // TODO Auto-generated method stub
- System.out.println(TAG + "onResume");
- super.onResume();
- }