Fragment允许将Activity拆分成多个完全独立封装的可重用组件,每个组件有他自己的生命周期和UI布局。Fragment不能单独使用,它必须依赖一个Activity存在,其生命周期也依赖于它所嵌入的Activity。
一个典型的Fragment生命周期如下图所示。
其生命周期与Activity类似。为验证其生命周期,测试程序如下:
创建Fragment:
public class FragmentTest extends Fragment{
private static String TAG="FragmentTest";
private String mFragmentName="";
private TextView TvShow;
public final static FragmentTest newInstance(String fragmentName){
FragmentTest ft=new FragmentTest();
Bundle bd=new Bundle(1);
bd.putString("name",fragmentName);
ft.setArguments(bd);
return ft;
};
/**
* 调用该方法时,fragement会被绑定到他所在的Activity中
*/
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
Log.w(TAG,mFragmentName+" onAttach");
}
/**
* Fragment的初始创建
*/
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
mFragmentName=getArguments().getString("name");
Log.w(TAG,mFragmentName+" onCreate");
}
/**
* 创建Fragment的用户界面时候调用
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.w(TAG,mFragmentName+" onCreateView");
return inflater.inflate(R.layout.fragment_main,container,false);
}
/**
* Fragment的UI已经创建,则调用该方法
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
TvShow=(TextView)getActivity().findViewById(R.id.fragment_detail_tv);
TvShow.setText(mFragmentName);
Log.w(TAG,mFragmentName+" onActivityCreated");
}
/**
* 在Fragment的可见生命周期中调用
*/
@Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.w(TAG,mFragmentName+" onStart");
}
/**
* 在活动的生命周期过程调用
*/
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.w(TAG,mFragmentName+" onResume");
}
/*
* 在活动的生命周期结束时调用
*/
@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.w(TAG,mFragmentName+" onPause");
}
/**
* 在可见生命周期结束时候调用
*/
@Override
public void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.w(TAG,mFragmentName+" onStop");
}
/**
* Fragment与View分离时,调用该方法
*/
@Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
Log.w(TAG,mFragmentName+" onDestroyView");
}
/**
* 在整个生命周期结束时调用该方法
*/
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.w(TAG,mFragmentName+" onDestroy");
}
/*
* 在Fragment与调用它的Activity分离时调用
*/
@Override
public void onDetach() {
// TODO Auto-generated method stub
super.onDetach();
Log.w(TAG,mFragmentName+" onDetach");
}
}
在onCreateView方法中写入fragment所需要的布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/fragment_detail_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
创建Activity的布局文件,该布局文件中id为fragment_detail的LinearLayout为将要填入Fragment的布局。
<?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">
<LinearLayout
android:id="@+id/fragment_ctrl"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/remove_fragment1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="remove test1"/>
<Button
android:id="@+id/add_fragment2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="add test2"/>
<Button
android:id="@+id/replace_fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="replace"/>
</LinearLayout>
<LinearLayout
android:id="@+id/fragment_detail"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"/>
</LinearLayout>
创建Activity:
package com.pigrush.fragment.fragmenttest;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity implements View.OnClickListener {
FragmentManager mFragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app_bar_main);
//在程序中动态添加Fragment
mFragmentManager=getFragmentManager();
FragmentTransaction fragmentTrans=mFragmentManager.beginTransaction();
if(savedInstanceState==null){
fragmentTrans.add(R.id.fragment_detail, FragmentTest.newInstance("test1"), "test1");
fragmentTrans.commit();
}
findViewById(R.id.remove_fragment1).setOnClickListener(this);
findViewById(R.id.add_fragment2).setOnClickListener(this);
findViewById(R.id.replace_fragment).setOnClickListener(this);
}
@Override
public void onClick(View v){
switch(v.getId()){
case R.id.remove_fragment1:
Fragment fragment=mFragmentManager.findFragmentByTag("test1");
FragmentTransaction fragmentTrans=mFragmentManager.beginTransaction();
fragmentTrans.remove(fragment);
fragmentTrans.commit();
break;
case R.id.add_fragment2:
FragmentTransaction fragmentTransAdd=mFragmentManager.beginTransaction();
fragmentTransAdd.add(R.id.fragment_detail, FragmentTest.newInstance("test2"), "test2");
fragmentTransAdd.commit();
break;
case R.id.replace_fragment:
FragmentTransaction fragmentTransReplace=mFragmentManager.beginTransaction();
fragmentTransReplace.replace(R.id.fragment_detail,FragmentTest.newInstance("test3"),"test3");
fragmentTransReplace.commit();
break;
}
}
}
启动Activiy并加入Fragment后,打印log如下所示:
04-19 13:26:12.043 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: onAttach
04-19 13:26:12.043 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onCreate
04-19 13:26:12.043 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onCreateView
04-19 13:26:12.062 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onActivityCreated
04-19 13:26:12.064 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onStart
04-19 13:26:12.064 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onResume
按home键将程序退到后台,log为:
04-19 13:27:05.801 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onPause
04-19 13:27:05.835 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onStop
将程序再次运行到前台:
04-19 13:27:35.927 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onStart
04-19 13:27:35.927 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onResume
点击back按钮退出程序:
04-19 13:28:05.651 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onPause
04-19 13:28:06.058 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onStop
04-19 13:28:06.058 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onDestroyView
04-19 13:28:06.059 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onDestroy
04-19 13:28:06.059 3085-3085/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onDetach
重新启动应用程序,点击“remove test1”,将“test1” remove掉,打印log如下:
04-19 14:04:05.530 25831-25831/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onPause
04-19 14:04:05.530 25831-25831/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onStop
04-19 14:04:05.530 25831-25831/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onDestroyView
04-19 14:04:05.531 25831-25831/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onDestroy
04-19 14:04:05.531 25831-25831/com.pigrush.fragment.fragmenttest W/FragmentTest: test1 onDetach
此时tag为“test1”的Fragment已经销毁。点击“add test2”,打印log如下:
04-19 14:23:20.140 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: onAttach
04-19 14:23:20.140 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test2 onCreate
04-19 14:23:20.140 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test2 onCreateView
04-19 14:23:20.140 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test2 onActivityCreated
04-19 14:23:20.141 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test2 onStart
04-19 14:23:20.141 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test2 onResume
此时tag为“test2”的Fragment创建并显示,点击“replace”,打印log如下:
04-19 14:26:07.435 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test2 onPause
04-19 14:26:07.435 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test2 onStop
04-19 14:26:07.435 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test2 onDestroyView
04-19 14:26:07.435 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test2 onDestroy
04-19 14:26:07.435 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test2 onDetach
04-19 14:26:07.435 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: onAttach
04-19 14:26:07.435 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test3 onCreate
04-19 14:26:07.435 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test3 onCreateView
04-19 14:26:07.435 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test3 onActivityCreated
04-19 14:26:07.435 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test3 onStart
04-19 14:26:07.435 10936-10936/com.pigrush.fragment.fragmenttest W/FragmentTest: test3 onResume
“test2”销毁被“test3”替换。
注:如果需要在创建Fragment传递参数时候,官方文档不建议在重写构造函数传入参数。
*Default constructor. Every fragment must have an empty constructor, so it can be instantiated when restoring its activity’s state. It is strongly recommended that subclasses do not have other constructors with parameters, since these constructors will not be called when the fragment is re-instantiated; instead, arguments can be supplied by the caller with setArguments(Bundle) and later retrieved by the Fragment withgetArguments().
Applications should generally not implement a constructor. The first place application code an run where the fragment is ready to be used is in onAttach(Activity), the point where the fragment is actually associated with its activity. Some applications may also want to implementonInflate(Activity, AttributeSet, Bundle) to retrieve attributes from a layout resource, though should take care here because this happens for the fragment is attached to its activity.*
具体原因可以参看http://www.tuicool.com/articles/j22E3u