› › 文章

Fragment生命周期的详情

文章目录

最近在看Android 6.0 Settings的源码,Fragment在很多地方都在使用,因此今天有空就复习一下。

一图胜千言,直接看图。(下图来源互联网)

图1、Fragment

图2、Activity

上面是Fragment和Activity(这个很熟悉吧)各自的生命周期,他们有些相同之处。

1、代码片段

MainActivity.java

public class MainActivity extends Activity {
	private int[] bt_left_ids = new int[] { R.id.main_bt_first,
			R.id.main_bt_second, R.id.main_bt_third };
	private First mFist = null;
	private Second mSecond = null;
	private Third mThird = null;
	private static Fragment currentFragment = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initUI();
	}

	private void initUI() {
		for (int i = 0; i < bt_left_ids.length; i++) {
			findViewById(bt_left_ids[i]).setOnClickListener(clickListener);
		}

		mFist = new First();
		mSecond = new Second();
		mThird = new Third();
		// 默认显示First
		currentFragment = mFist;
		setFragment(mFist);
		return;
	}

	private OnClickListener clickListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			switch (v.getId()) {
			case R.id.main_bt_first:
				setFragment(currentFragment, mFist);
				break;
			case R.id.main_bt_second:
				setFragment(currentFragment, mSecond);
				break;
			case R.id.main_bt_third:
				setFragment(currentFragment, mThird);
				break;
			default:
				break;
			}
		}
	};

	/**
	 * 方法一,这种每次都添加替换,效率低
	 * 
	 * @param fragment
	 */
	private void setFragment(Fragment fragment) {
		if (null == fragment) {
			return;
		}
		// 如果相同就没必要更新了
		if (currentFragment == fragment) {
			return;
		}
		currentFragment = fragment;
		// 每次都需要重新初始化
		FragmentTransaction mFragmentTransaction = getFragmentManager()
				.beginTransaction();
		mFragmentTransaction.replace(R.id.main_content, fragment);
		mFragmentTransaction.commitAllowingStateLoss(); //

		return;
	}

	/**
	 * 方法二
	 * 
	 * @param from
	 * @param to
	 */
	private void setFragment(Fragment from, Fragment to) {
		// 判断是否相同,如果是就不需要更新
		if (from == to) {
			return;
		}
		currentFragment = to;
		// 每次都需要重新初始化
		FragmentTransaction mFragmentTransaction = getFragmentManager()
				.beginTransaction();
		// 判断是否已经添加过,如果没有就先添加,在显示
		if (!to.isAdded()) {
			mFragmentTransaction.hide(from).add(R.id.main_content, to).commit();
		} else {
			mFragmentTransaction.hide(from).show(to).commit();
		}
		return;
	}
}

First.java

public class First extends Fragment {

	private String TAG = "frag";
	private View view = null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		Log.d(TAG, "--First----------onCreate----------");
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		Log.d(TAG, "--First----------onCreateView----------");
		view = inflater.inflate(R.layout.activity_first, container, false);
		return view;
	}

	@Override
	public void onAttach(Activity activity) {
		// TODO Auto-generated method stub
		Log.d(TAG, "--First----------onAttach----------");
		super.onAttach(activity);
	}

	@Override
	public void onDetach() {
		// TODO Auto-generated method stub
		Log.d(TAG, "--First----------onDetach----------");
		super.onDetach();
	}

	@Override
	public void onResume() {
		// TODO Auto-generated method stub
		Log.d(TAG, "--First----------onResume----------");
		super.onResume();
	}

	@Override
	public void onStart() {
		// TODO Auto-generated method stub
		Log.d(TAG, "--First----------onStart----------");
		super.onStart();
	}

	@Override
	public void onStop() {
		// TODO Auto-generated method stub
		Log.d(TAG, "--First----------onStop----------");
		super.onStop();
	}

	@Override
	public void onPause() {
		// TODO Auto-generated method stub
		Log.d(TAG, "--First----------onPause----------");
		super.onPause();
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		Log.d(TAG, "--First----------onActivityCreated----------");
		super.onActivityCreated(savedInstanceState);
	}

	@Override
	public void onDestroyView() {
		// TODO Auto-generated method stub
		Log.d(TAG, "--First----------onDestroyView----------");
		super.onDestroyView();
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.d(TAG, "--First----------onDestroy----------");
		super.onDestroy();
	}
}

activity_main.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" >

    <LinearLayout
        android:id="@+id/main_layout"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/main_bt_first"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="First" />

        <Button
            android:id="@+id/main_bt_second"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="Second" />

        <Button
            android:id="@+id/main_bt_third"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="Third" />
    </LinearLayout>

    <FrameLayout
        android:id="@+id/main_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/main_layout" />

</RelativeLayout>

2、生命周期分析

额额,进入退出生命周期就是如下。

1、使用方法一:setFragment(Fragment fragment)
	/**
	 * 方法一,这种每次都添加替换,效率低
	 * 
	 * @param fragment
	 */
	private void setFragment(Fragment fragment) {
		if (null == fragment) {
			return;
		}
		// 如果相同就没必要更新了
		if (currentFragment == fragment) {
			return;
		}
		currentFragment = fragment;
		// 每次都需要重新初始化
		FragmentTransaction mFragmentTransaction = getFragmentManager()
				.beginTransaction();
		mFragmentTransaction.replace(R.id.main_content, fragment);
		mFragmentTransaction.commitAllowingStateLoss(); //

		return;
	}

从Second Fragment 切到 First Fragment,每次切换时都会退出上一个Fragment,这样效率就低了。

#从Second Fragment 切到 First Fragment
--Second----------onCreate----------
--Second----------onCreateView----------
--Second----------onDestroyView----------
--Second----------onDestroy----------
--First----------onAttach----------
--First----------onCreate----------
--First----------onCreateView----------
--First----------onActivityCreated----------
--First----------onStart----------
--First----------onResume----------
2、使用方法二:setFragment(Fragment from, Fragment to)
	/**
	 * 方法二
	 * 
	 * @param from
	 * @param to
	 */
	private void setFragment(Fragment from, Fragment to) {
		// 判断是否相同,如果是就不需要更新
		if (from == to) {
			return;
		}
		currentFragment = to;
		// 每次都需要重新初始化
		FragmentTransaction mFragmentTransaction = getFragmentManager()
				.beginTransaction();
		// 判断是否已经添加过,如果没有就先添加,在显示
		if (!to.isAdded()) {
			mFragmentTransaction.hide(from).add(R.id.main_content, to).commit();
		} else {
			mFragmentTransaction.hide(from).show(to).commit();
		}
		return;
	}

从Second Fragment 切到 First Fragment,第一次进入后会保存,再次切换时就不需要重新加载。

#第一次进入
--First----------onAttach----------
--First----------onCreate----------
--First----------onCreateView----------
--First----------onActivityCreated----------
--First----------onStart----------
--First----------onResume----------

#终结Activity(退出App)
--First----------onPause----------
--First----------onStop----------
--First----------onDestroyView----------
--First----------onDestroy----------
--First----------onDetach----------

3、Fragment生命周期讲解

以下部分文章摘抄于《Fragment 生命周期的详情》,感谢分享。

onAttach():执行该方法时,Fragment与Activity已经完成绑定,该方法有一个Activity类型的参数,代表绑定的Activity,这时候你可以执行诸如mActivity = activity的操作。

onCreate():初始化Fragment。可通过参数savedInstanceState获取之前保存的值。

onCreateView():初始化Fragment的布局。加载布局和findViewById的操作通常在此函数内完成,但是不建议执行耗时的操作,比如读取数据库数据列表。

onActivityCreated():执行该方法时,与Fragment绑定的Activity的onCreate方法已经执行完成并返回,在该方法内可以进行与Activity交互的UI操作,所以在该方法之前Activity的onCreate方法并未执行完成,如果提前进行交互操作,会引发空指针异常。

onStart():执行该方法时,Fragment由不可见变为可见状态。

onResume():执行该方法时,Fragment处于活动状态,用户可与之交互。

onPause():执行该方法时,Fragment处于暂停状态,但依然可见,用户不能与之交互。

onSaveInstanceState():保存当前Fragment的状态。该方法会自动保存Fragment的状态,比如EditText键入的文本,即使Fragment被回收又重新创建,一样能恢复EditText之前键入的文本。

onStop():执行该方法时,Fragment完全不可见。

onDestroyView():销毁与Fragment有关的视图,但未与Activity解除绑定,依然可以通过onCreateView方法重新创建视图。通常在ViewPager+Fragment的方式下会调用此方法。

onDestroy():销毁Fragment。通常按Back键退出或者Fragment被回收时调用此方法。

onDetach():解除与Activity的绑定。在onDestroy方法之后调用。

发表评论