Fragment生命周期的详情

Android  2018年8月7日 pm7:46发布6年前 (2018)更新 91es.com站长
104 0 0

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

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

Fragment生命周期的详情

图1、Fragment

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 生命周期的详情》,感谢分享。

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方法之后调用。

 历史上的今天

  1. 2024: Android String占位格式化(0条评论)
  2. 2023: MediaPlayer源码介绍2(0条评论)
  3. 2020: [摘]停止ListView滑动-Android(0条评论)
  4. 2019: 设计模式之观察者模式(0条评论)
  5. 2019: 朱光潜:读书不在多,在于选得精,读得彻底(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

梁文道 :清贫与富贵

我在台湾念小学的时候,有一个同学是军人子弟,他的父亲大概很早就退伍了,所以没有领到太多的长俸和福利,后来务农为生,日子过得很辛苦。虽然贫困,但他家的桌子总是擦得一尘不染,厕所地板亮得反光。每次到他家吃饭,我都震慑于老伯伯一口洪亮的山东腔,以及他那威严的仪容。而他的孩子,我这位同学,尽管一身旧衣早...

Android.mk介绍之一基础语法

Android.mk一系列文章计划介绍内容如下几个章节:1、Android.mk介绍之一基础语法2、Android.mk介绍之二预编译生成的文件类型3、Android.mk介绍之三引用静态库,动态库1、Android.mk的基本语法对于Android开发,尤其是Android源码开...

[摘]Android开发之Shape详细解读

这篇文章总结得很详细,因此摘抄于此,以便自己查询和学习。原文如下日常开发中,我们会遇到一些Button、Textview...等控件的背景是圆角矩形、圆形...等,和android默认的控件背景矩形不一致,此时shape的作用就体现出来了,我们可以根据shape属性画出很多我们意想不到的背景图...

汪曾祺:端午的鸭蛋

家乡的端午,很多风俗和外地一样。系百索子。五色的丝线拧成小绳,系在手腕上。丝线是掉色的,洗脸时沾了水,手腕上就印得红一道绿一道的。做香角子。丝线缠成小粽子,里头装了香面,一个一个串起来,挂在帐钩上。贴五毒。红纸剪成五毒,贴在门槛上。贴符。这符是城隍庙送来的。城隍庙的老道士还是我的寄名干爹,他每年端午...

Android Studio重构清除无引用资源

前言Android开发中,发现移植的APP模块存有很多图片和xml等资源,至于是否有引用,不去查询是不太好知道的。但是Android Studio有个功能,也就是Android Studio Refactor/Remove Unused Resources【重构,移除没有引用的资源】。PS:...

JS监听滚动条位置变化

有时候我们需要监听浏览器中上下滚动的位置来改变一些元素的属性隐藏或者显示,比如91易搜中下拉达到一定高度后搜索框会固定在顶部。(可以前去看看效果)如果我们要实现这效果,就需要监听滚动条的Y轴位置的变化,根据Y轴的位置来改变某些元素的属性值。闲话少说,直接附上代码(下面是改变类heade...