Fragment生命周期及相关方法简介
1、Activity与Fragment生命周期对比
2、生命周期相关方法介绍
onAttach()
public void onAttach(Context context) {
mCalled = true;
final Activity hostActivity = mHost == null ? null : mHost.getActivity();
if (hostActivity != null) {
mCalled = false;
onAttach(hostActivity);
}
}
// 根据此源码的注释可以知道,当一个fragment第一次绑定他的上下文环境之后会调用这个方法
onCreate()
public void onCreate(@Nullable Bundle savedInstanceState) {
mCalled = true;
restoreChildFragmentState(savedInstanceState);
if (mChildFragmentManager != null
&& !mChildFragmentManager.isStateAtLeast(Fragment.CREATED)) {
mChildFragmentManager.dispatchCreate();
}
}
/**
此方法用于初始化一个fragment,将在onAttach()方法之后,在onCreateView()方法之前调用,其中的参数onCreateView
是用于保存fragment的相关信息,当此fragment重新创建的时候,调用restoreChildFragmentState(savedInstanceState)
恢复相关的状态信息,我们继续深入看看restoreChildFragmentState方法的具体实现
*/
void restoreChildFragmentState(@Nullable Bundle savedInstanceState) {
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(
FragmentActivity.FRAGMENTS_TAG);
if (p != null) {
if (mChildFragmentManager == null) {
instantiateChildFragmentManager();
}
mChildFragmentManager.restoreAllState(p, mChildNonConfig);
mChildNonConfig = null;
mChildFragmentManager.dispatchCreate();
}
}
}
/**
可以看出当savedInstanceState参数不为null,并且由此参数得到的Parcelable对象不为null的时候,程序会调用
mChildFragmentManager.restoreAllState(p, mChildNonConfig)恢复所有的状态
*/
onCreateView()
@Nullable
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return null;
}
/**
此方法用于实例化该fragment,其中返回值是该fragment的UI,当为非图形化的fragment的时候可以返回null
此方法是在onCreate()方法和onActivityCreated()方法之间调用。
@param inflater : 用于填充fragment的UI布局
@param container : fragment的UI所关联的父View
@param savedInstanceState : 用于恢复该fragment的状态信息
值得注意的是,fragment中UI布局大多数是在这个方法中使用inflater.inflate()方法进行填充,但是使用该方法的
时候一定要注意方法中的参数!!!
*/
onViewCreated()
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {}
/**此方法是执行的时机是在onCreateView()执行返回值之后会立刻执行,但是又是在所有的状态恢复之前,
这就使子类在知道view结构创建完成之后,立刻去初始化自身
@param view : onCreateView()方法返回的View
@param savedInstanceState : 用于恢复该fragment的状态信息*/
onActivityCreated()
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
mCalled = true;
}
// 此方法执行的时机是该fragment所依附的activity执行完onCreate方法之后执行,其参数可用来恢复相关的状态信息
onDestroy()
public void onDestroy() {
mCalled = true;
//Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager
// + " mLoaderManager=" + mLoaderManager);
if (!mCheckedForLoaderManager) {
mCheckedForLoaderManager = true;
mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
}
if (mLoaderManager != null) {
mLoaderManager.doDestroy();
}
}
// 当fragment不在使用的时候会调用这个方法进行销毁,此方法会在onStop()之后onDetach()方法之前调用
onDetach()
public void onDetach() {
mCalled = true;
}
// 当fragment不在关联activity的时候调用此方法
3、其余方法杂记
setUserVisibleHint()
public void setUserVisibleHint(boolean isVisibleToUser) {
if (!mUserVisibleHint && isVisibleToUser && mState < STARTED
&& mFragmentManager != null && isAdded()) {
mFragmentManager.performPendingDeferredStart(this);
}
mUserVisibleHint = isVisibleToUser;
mDeferStart = mState < STARTED && !isVisibleToUser;
}
/**
可以根据isVisibleToUser参数来判断该fragment是否可见,在viewpager和fragment组合使用的时候,viewpager
有预加载的机制,即viewpager会在加载的初期就加载多个界面,若是加载的数据较多,就会造成相关加载的延迟,造成交互
感官的问题,所以可以采用一些别的措施,比如懒加载方法,即当该fragment可见的时候才开始加载,其逻辑方法就是写在
setUserVisibleHint()方法中
*/
onSaveInstanceState()
protected void onSaveInstanceState(Bundle outState) {
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
getApplication().dispatchActivitySaveInstanceState(this, outState);
}
/**
此方法是在某些情况下保存状态信息的,其执行的时机是在onStop()方法之前,但是就不一定是在onPause()方法之前或者之后了,
其中的参数是是Bundle类型的对象,就是用来存储相关信息的。
*/
其用法如下:
//存储状态信息
@Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
//重写此方法,存储信息
String content = etCon.getText().toString();
outState.putString("inputCon", content);
}
//获取保存的状态信息,恢复界面数据(当然在fragment中但凡方法中有Bundle savedInstanceState参数的均可用来恢复状态)
@Override
public void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
//恢复之前输入框的内容
if(savedInstanceState != null){
etCon.setText(savedInstanceState.getString("inputCon", ""));
}
}
/**
不过在值得注意时,在使用onSaveInstanceState()方法时注意使用的时机,不是所有的情况下该方法都会被调用,比如点击了
后退键,主动关闭了当前界面,就会走onPause() --> onStop() --> onDestroy() 而onSaveInstanceState()
并不会被调用,onSaveInstanceState() 只有在系统即将要自动清理销毁Activity或Fragment前才会调用,比如:
♥ 由于重力感应 手机从竖屏变为横屏
♥ 手机点击Home键和长按Home键
♥ 点击电源键锁屏时
♥ 从当前Activity跳到另一个Activity
♥ 应用内存不足即将自动销毁时等情况
*/