Fragment学习总结
2019-10-05 本文已影响0人
九叶轻尘
Fragment学习总结
Fragment:碎片。可以看成Activity的一个控件,必须依赖于Activity才能存在。但是不同的是,这个“控件”有着自己的生命周期,和activity的生命周期类似,只是会多几个环节。在Android开发过程中有两个fragment,分别在app包下和v4包下,使用有区别,需要注意。
Fragment生命周期
Fragment的生命周期生命周期 | 调用时间 |
---|---|
onAttace() | 当fragment被加入到activity时调用 |
onCreate() | 系统创建fragment的时候回调 |
onCreateView() | 第一次使用的时候 fragment会在这上面画一个layout出来, 为了可以画控件 要返回一个 布局的view,也可以返回null。在这一步中加载布局文件 |
onActivityCreated() | 当activity中的onCreate方法执行完后调用 |
onStart() | 和activity一致,启动Fragement 启动时回调,,此时Fragement可见 |
onResume() | 和activity一致 在activity中运行是可见的。激活, Fragement 进入前台, 可获取焦点时激活 |
onPause() | 和activity一致 其他的activity获得焦点,这个仍然可见 |
onStop() | 和activity一致, fragment不可见的, 可能情况:activity被stopped了或者fragment被移除但被加入到回退栈中,一个stopped的fragment仍然是活着的如果长时间不用也会被移除 |
onDestroyView() | Fragment中的布局被移除时调用。表示fragemnt销毁相关联的UI布局, 清除所有跟视图相关的资源 |
onDestroy() | 销毁fragment对象, 跟activity类似了 |
onDetach() | Fragment和Activity解除关联的时候调用,脱离activity |
Fragment的管理者
- FragmentManager:可以在Activity中管理fragment。可以通过getFragmentManager()方法获取这个对象,在v4的包中可以通过getSupportFragmentManager()方法获取。使用findFragmentById()或者findFragmentByTag()方法可以得到Activity中存在的fragment。也可以判断是否为空。
- FragmentTransaction:碎片事物。将对Fragment产生的是操作封装成事物,由此构成一个集合,执行相应的结果。FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();这个里面存放了很多很多关于Fragment的操作。设置完操作之后,使用commit()方法提交事务,就能执行了。
FragmentManager真正的实现类是FragmentManagerImpl,FragmentTransaction的实现类是BackStackRecord。在fragmentManager.beginTranaction()就是在创建一个BackStackRecord对象,这个对象会持有FragmentManagerImpl对象的引用。源码如下。
//创建BackStackRecord对象
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
在BackStackRecord中对Fragment的add,remove等操作都会被封装成Op对象(Op是BackStackRecord的内部类),BackStackRecord中有一个ArrayList来存储这些Op操作对象。
//封装着对Fragment的操作,cmd值映射着操作类型
static final class Op {
int cmd;
Fragment fragment;
int enterAnim;
int exitAnim;
int popEnterAnim;
int popExitAnim;
Op() {
}
Op(int cmd, Fragment fragment) {
this.cmd = cmd;
this.fragment = fragment;
}
}
//将操作保存
void addOp(BackStackRecord.Op op) {
this.mOps.add(op);
op.enterAnim = this.mEnterAnim;
op.exitAnim = this.mExitAnim;
op.popEnterAnim = this.mPopEnterAnim;
op.popExitAnim = this.mPopExitAnim;
}
在执行commit()的时候,才开始执行之前设置的对Fragment的管理操作。commit()最后执行的是commitInternal()方法。源码如下。
int commitInternal(boolean allowStateLoss) {
//每一个事物只能commit一次
if (this.mCommitted) {
throw new IllegalStateException("commit already called");
} else {
if (FragmentManagerImpl.DEBUG) {
Log.v("FragmentManager", "Commit: " + this);
LogWriter logw = new LogWriter("FragmentManager");
PrintWriter pw = new PrintWriter(logw);
this.dump(" ", (FileDescriptor)null, pw, (String[])null);
pw.close();
}
this.mCommitted = true;
//是否需要添加到回退栈中
if (this.mAddToBackStack) {
//将事物添加进去,获得存储位置的Index
this.mIndex = this.mManager.allocBackStackIndex(this);
} else {
this.mIndex = -1;
}
//执行这个事务
this.mManager.enqueueAction(this, allowStateLoss);
return this.mIndex;
}
}
在执行commit时,如果allowStateLoss为false则会判断Activity的状态是否能够提交,不能提交则会抛出异常。
public void enqueueAction(FragmentManagerImpl.OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
this.checkStateLoss();
}
synchronized(this) {
if (!this.mDestroyed && this.mHost != null) {
if (this.mPendingActions == null) {
this.mPendingActions = new ArrayList();
}
this.mPendingActions.add(action);
//这里才会真正执行这个事物
this.scheduleCommit();
} else if (!allowStateLoss) {
throw new IllegalStateException("Activity has been destroyed");
}
}
}