这篇文章主要介绍fragment的生命周期而不是用法。
由于fragment不是独立的组件,需要被添加到Acitvity中,所以Fragment的生命周期和Activity存在一定的关联
和fragment生命周期有关的的几个重要回调方法:
onAttach(Activity) fragment被添加到activity时被调用
onCreate(Bundle) fragment创建时调用
onCreateView(LayoutInflater, ViewGroup, Bundle) fragment初始化界面时调用
onActivityCreated(Bundle) 包含fragment的activity的onCreate方法执行完毕后调用
onStart() fragment可见时,和activitiy的onStart相关联
onResume() 和activitiy的onResume相关联
onPause() activity onPause或者fragment被移除时
onStop() activity onStop或者fragment被移除时
onDestroyView() fragment被移除时,关联的view正在被移除时调用
onDestroy(),onDetach() fragment被移除时调用
API GUIDE给出的图示:
还有1个示意图对比了activity和fragment的生命周期
可以看出,fragment的onAttatch,onCreate,onCreateView,onActivityCreated是fragment的创建阶段,相当于Activity的创建阶段,onStart,onResume,onPause,onStop的流程都和Activity一样,销毁阶段,包含了onDestroyView,onDestroy,onDetach方法。
下面用例子来演示fragment的生命周期:
初次启动的Activity:
MainActivity.java
public class MainActivity extends Activity {
private Button goFragment;
private Button goActivity;
private boolean first = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("test", "Activity-onCreate");
initViews();
}
@Override
protected void onResume() {
super.onResume();
Log.v("test", "Activity-onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.v("test", "Activity-onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.v("test", "Activity-onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.v("test", "Activity-onDestroy");
}
private void initViews() {
goFragment = (Button) findViewById(R.id.go_fragment);
goActivity = (Button) findViewById(R.id.go_activity);
goFragment.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container, new FragmentB());
ft.commit();
}
});
goActivity.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, Activity2.class));
}
});
}
@Override
protected void onStart() {
Log.v("test", "Activity-onStart");
super.onStart();
//防止重复加载fragment
if(first) {
first = false;
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.container, new FragmentA());
ft.commit();
}
}
}
布局文件:
<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:gravity="center_horizontal"
android:orientation="vertical"
tools:context=".MainActivity" >
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="350dp"
/>
<Button
android:id="@+id/go_fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="go fragment2" />
<Button
android:id="@+id/go_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="go Activity2" />
</LinearLayout>
界面上一个frameLayout,用来装载fragment,2个按钮,一个用来替换fragment,一个用来跳转activity
FragmentA的代码:
public class FragmentA extends Fragment {
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.v("test", "FragmentA:" + "onAttach");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("test", "FragmentA:" + "onCreate");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.v("test", "FragmentA:" + "onCreateView");
return inflater.inflate(R.layout.fragment1, null);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.v("test", "FragmentA:" + "onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
Log.v("test", "FragmentA:" + "onStart");
}
@Override
public void onResume() {
super.onResume();
Log.v("test", "FragmentA:" + "onResume");
}
@Override
public void onPause() {
super.onPause();
Log.v("test", "FragmentA:" + "onPause");
}
@Override
public void onStop() {
super.onStop();
Log.v("test", "FragmentA:" + "onStop");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.v("test", "FragmentA:" + "onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.v("test", "FragmentA:" + "onDestroy");
}
@Override
public void onDetach() {
super.onDetach();
Log.v("test", "FragmentA:" + "onDetach");
}
}
Activity和fragment的回调中都进行了日志打印。
在Acitivity的onStart方法中,调用了如下代码:
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.container, new FragmentA());
ft.commit();
作用是在Acitivity启动后在界面上加载一个fragment。
启动程序,观察控制台输出:
10-27 18:20:23.423: V/test(3128): Activity-onCreate
10-27 18:20:23.423: V/test(3128): Activity-onStart
10-27 18:20:23.423: V/test(3128): FragmentA:onAttach
10-27 18:20:23.423: V/test(3128): FragmentA:onCreate
10-27 18:20:23.423: V/test(3128): FragmentA:onCreateView
10-27 18:20:23.423: V/test(3128): FragmentA:onActivityCreated
10-27 18:20:23.423: V/test(3128): FragmentA:onStart
10-27 18:20:23.423: V/test(3128): Activity-onResume
10-27 18:20:23.423: V/test(3128): FragmentA:onResume
解释:MainActivity onCreate执行后,接着执行onStart,onStart中添加了fragment到framelayout中,这时fragment的onAttach回调被调用。接着是onCreate,onCreateView,onActivityCreated依次被回调,现在点击gofragment2按钮,移除fragment1,加入fragment2,观察logcat:
10-27 18:44:23.513: V/test(3128): FragmentA:onPause
10-27 18:44:23.513: V/test(3128): FragmentA:onStop
10-27 18:44:23.513: V/test(3128): FragmentA:onDestroyView
10-27 18:44:23.513: V/test(3128): FragmentA:onDestroy
10-27 18:44:23.513: V/test(3128): FragmentA:onDetach
正是第一张图片所示的从前台到销毁的过程。
现在重启程序,试着点击第二个按钮go Activity2,观察logcat输出:
10-27 19:08:34.253: V/test(3128): FragmentA:onPause
10-27 19:08:34.253: V/test(3128): Activity-onPause
10-27 19:08:34.573: V/test(3128): FragmentA:onStop
10-27 19:08:34.573: V/test(3128): Activity-onStop
可以看到,当前Activity被覆盖后,fragment的onPause,onStop和Activity的onPause,onStop同时被调用。
这时,按物理返回键,退出第二个Activity,回到第一个Activity,观察logcat输出:
10-27 19:29:07.063: V/test(9162): Activity-onStart
10-27 19:29:07.063: V/test(9162): FragmentA:onStart
10-27 19:29:07.063: V/test(9162): Activity-onResume
10-27 19:29:07.063: V/test(9162): FragmentA:onResume
可见,在activity重新进入前台,执行onStart和onResume时,fragment也执行一样的操作
现在修改一下跳转activity的按钮的代码,让当前activity finish
goActivity.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, Activity2.class));
finish();
}
});
重启程序,点击跳转activity的按钮,观察输出:
10-27 19:33:54.893: V/test(9810): FragmentA:onPause
10-27 19:33:54.893: V/test(9810): Activity-onPause
10-27 19:33:55.213: V/test(9810): FragmentA:onStop
10-27 19:33:55.213: V/test(9810): Activity-onStop
10-27 19:33:55.213: V/test(9810): FragmentA:onDestroyView
10-27 19:33:55.213: V/test(9810): FragmentA:onDestroy
10-27 19:33:55.213: V/test(9810): FragmentA:onDetach
10-27 19:33:55.213: V/test(9810): Activity-onDestroy