云建站系统前三名,手机app设计软件,网站设计模板含数据库,做社区生意的网站上一篇Android#xff1a;FragmentTransaction我们大概介绍了FragmentManager的大致工作流程#xff0c;知道了每个动作都会添加到Op队列里#xff0c;并由FragmentTransaction进行管理#xff0c;那么我们就来看看FragmentTransaction的具体内容。
首先FragmentTransacti…上一篇AndroidFragmentTransaction我们大概介绍了FragmentManager的大致工作流程知道了每个动作都会添加到Op队列里并由FragmentTransaction进行管理那么我们就来看看FragmentTransaction的具体内容。
首先FragmentTransaction中定义了每个动作的常量值。 static final int OP_NULL 0;static final int OP_ADD 1;static final int OP_REPLACE 2;static final int OP_REMOVE 3;static final int OP_HIDE 4;static final int OP_SHOW 5;static final int OP_DETACH 6;static final int OP_ATTACH 7;static final int OP_SET_PRIMARY_NAV 8;static final int OP_UNSET_PRIMARY_NAV 9;static final int OP_SET_MAX_LIFECYCLE 10;
在这些值里面我们看到了非常熟悉的一些操作比如addhidereplace等每个动作都对应一个值。
有了值就会为每个动作分配定义一个对象。内部类Op。 static final class Op {//每个动作对应的命令数值int mCmd;//要操作的那个fragmentFragment mFragment;//进入动画int mEnterAnim;//退出时动画int mExitAnim;int mPopEnterAnim;int mPopExitAnim;//声明周期状态Lifecycle.State mOldMaxState;Lifecycle.State mCurrentMaxState;}
那每个动作是如何添加到事务的呢当我们调用事务的addhideshow等操作时从前面文章知道 FragmentManager fragmentManager getSupportFragmentManager();FragmentTransaction transaction fragmentManager.beginTransaction();
这个transaction其实是BackStackRecord对象所以会调用BackStackRecord中对应的方法比如hide操作。
//BackStackRecord.javapublic FragmentTransaction hide(NonNull Fragment fragment) {......//调用父类return super.hide(fragment);}//父类FragmentTransaction.javapublic FragmentTransaction hide(NonNull Fragment fragment) {addOp(new Op(OP_HIDE, fragment));return this;}
最终调用父类的addOp方法创建了一个Op对象并传入OP_HIDE值和要操作的Fragment对象然后将其添加到mOps列表中。 ArrayListOp mOps new ArrayList();void addOp(Op op) {mOps.add(op);op.mEnterAnim mEnterAnim;op.mExitAnim mExitAnim;op.mPopEnterAnim mPopEnterAnim;op.mPopExitAnim mPopExitAnim;}
我们在添加fragment到事务时add方法有两个重载方法。
transaction.add(f1,f1);
transaction.add(R.id.layout_f,f1,f1);
一个是不传容器id一个需要传第一个方法其实就是调用第二个方法然后id传0。 public FragmentTransaction add(NonNull Fragment fragment, Nullable String tag) {doAddOp(0, fragment, tag, OP_ADD);return this;}
对于第二个方法我们来看看。
void doAddOp(int containerViewId, Fragment fragment, Nullable String tag, int opcmd) {//反射final Class? fragmentClass fragment.getClass();final int modifiers fragmentClass.getModifiers();//检查fragment是否是匿名类是不是public的是不是静态类是不是嵌套类等if (fragmentClass.isAnonymousClass() || !Modifier.isPublic(modifiers)|| (fragmentClass.isMemberClass() !Modifier.isStatic(modifiers))) {throw new IllegalStateException(Fragment fragmentClass.getCanonicalName() must be a public static class to be properly recreated from instance state.);}//如果有标签tagif (tag ! null) {//检查tag不允许修改已经存在的tagif (fragment.mTag ! null !tag.equals(fragment.mTag)) {throw new IllegalStateException(Cant change tag of fragment fragment : was fragment.mTag now tag);}fragment.mTag tag;}//如果设置里容器Idif (containerViewId ! 0) {//如果没有为容器设置IDif (containerViewId View.NO_ID) {throw new IllegalArgumentException(Cant add fragment fragment with tag tag to container view with no id);}//如果fragment已经有容器Id了不允许变更if (fragment.mFragmentId ! 0 fragment.mFragmentId ! containerViewId) {throw new IllegalStateException(Cant change container ID of fragment fragment : was fragment.mFragmentId now containerViewId);}fragment.mContainerId fragment.mFragmentId containerViewId;}//添加Op到队列addOp(new FragmentTransaction.Op(opcmd, fragment));
}
代码做了注释就不在具体描述了。
再来看attach和detach方法detach会将fragment从UI界面移除即使调用show也无法再次显示出来。调用attach后fragment会重新显示在界面上。 findViewById(R.id.tv_1).setOnClickListener((v - {FragmentTransaction t fragmentManager.beginTransaction();t.detach(f1);t.commitNow();}));findViewById(R.id.tv_2).setOnClickListener((v - {FragmentTransaction t fragmentManager.beginTransaction();t.attach(f1);t.commitNow();}));