FragmentTransaction动态切换详解

Fragment常用的三个类
1,android.app.Fragment 主要用于定义Fragment,其实是对 View 的封装,它持有 view,containerView, fragmentManager, childFragmentManager 等信息
2,android.app.FragmentManager 主要用于在Activity中操作Fragment,它定义了对一个Activity/Fragment 中 添加进来的 Fragment 列表、Fragment回退栈的操作、管理方法,还定义了获取事务对象的方法
3,android.app.FragmentTransaction 定义了对Fragment 添加、替换、隐藏等操作,还有四种提交方法,具体实现是在 BackStackRecord 中

Fragment的主要有静态和动态两种添加方式,如果使用V4包中的Fragment,则对应的Activity需要继承自同样来自于V4包的FragmentActivity。V4包中的Fragment相对于系统自带的Fragment功能更强大一些,其中V4包需要在gradle文件的dependencies中动态引入。

获取FragmentManage的方式
1,getSupportFragmentManager():在Activity中使用Fragment的管理器,对所有Fragment进行管理
2,getFragmentManager():与 getSupportFragmentManager()功能是一样的,只是在Fragment中使用
3,getChildFragmentManager():在Fragment嵌套使用中经常用到,在fragment创建childFragment的时候,需要使用getChildFragmentManager(),使用getFragmentManager()会导致内存泄漏

FragmentManager的常用api
1,getFragments():可以获取所有创建时候add进去的所有Fragment;通常可以通过这个api来获取需要指定操作的fragment对象,2,findFragmentById:在activity中通过id获取静态添加的fragment
2,findFragmentByTag(String tag): 通过TAG获取指定的Fragment;这个TAG,是在创建Fragment时,调用addToBackStack(String tag)进行绑定关系的
3,popBackStack(): 弹出栈顶fragment
4,popBackStack(String tag,int flags):
如果tag为null,flags为0时,弹出回退栈中最上层的那个fragment
如果tag为null ,flags为1时,弹出回退栈中所有fragment
如果tag不为null,那就会找到这个tag所对应的fragment,flags为0时,弹出该 fragment以上的Fragment,如果是1,弹出该fragment(包括该fragment)以上的fragment
5,popBackStackImmediate相关的方法与上面逻辑是一样的与上面不同的是,在调用的时候会立即执行弹出
6,getBackStackEntryCount():获取回退栈中的元素个数
7,getBackStackEntryAt(int index):根据索引获取回退栈中的某个元素
8,添加或者移除一个监听器
public abstract void addOnBackStackChangedListener(OnBackStackChangedListener listener);
public abstract void removeOnBackStackChangedListener(OnBackStackChangedListener listener);
9,还定义了将一个 Fragment 实例作为参数传递
public abstract void putFragment(Bundle bundle, String key, Fragment fragment);
public abstract Fragment getFragment(Bundle bundle, String key);

FragmentTransaction的主要操作方法
1,add():将一个Fragment实例对象添加到集合列表的尾部,当展示的时候会在activity的最上层,如果队列中已有fragment,并且展示在最上层,则用add()新添加的fragment不会展示,只有当remove或者hide掉已存在的fragment,新添加的fragment才会展示。add()调用fragment的生命周期:onAttach,onCreate,onCreateView,onActivityCreated,onStart,onResume
2,remove():将一个Fragment实例对象从存储的集合列表中移除,并且将其从UI界面中销毁。remove()调用fragment的生命周期:onPause,onStop,onDestroyView,onDestroy,onDetach
3,replace():清空存储集合列表,将当前的Fragment实例对象添加到存储的链表尾部,当展示的时候会在activity的最上层。如果队列中已经存在该fragment,不会调用该fragment的生命周期,如果该fragment处于显示状态,则不变,如果没有,也显示不出来。会先调用新添加fragment的生命周期:onAttach,onCreate,然后调用被移除fragment的生命周期:onPause,onStop,onDestroyView,onDestroy,onDetach;最后再接着调用新添加fragment的生命周期:onCreateView,onActivityCreated,onStart,onResume(新增加一个fragment都调用这套方法)
4,hide():将一个fragment,从展示状态隐藏起来,实例对象不被销毁。hide()不调用fragment的生命周期,调用fragment的onHiddenChanged方法
5,show():将一个fragment实例对象,展示出来。show()和hide()配合使用,也不调用fragment的生命周期,调用fragment的onHiddenChanged方法,可以用fragment.isAdded()判断该fragment是否在队列中,如果在可以直接调用show()
6,attach():通过fragment的onCreateView()的重建视图,并且被重新加入到add的队列中,并且处于队列头部。attach()调用fragment的生命周期:onCreateView,onActivityCreated,onStart,onResume
7,detach():将视图View和Fragment分离,视图View也会从ViewTree中删除,还会将Fragment从add的队列中删除,所以在调用isAdd方法的时候返回的是false,但实例对象本身是还存在的,通过FragmentManager的findFragmentByTag还可以获取到实例对象。detach()调用fragment的生命周期:onPause,onStop,onDestroyView
8,commit():在主线程中异步执行,其实也是 Handler 抛出任务,等待主线程调度执行。如果想立即执行可以调用executePendingTransactions()。commit() 需要在宿主 Activity 保存状态之前调用,否则会报错。这是因为如果 Activity 出现异常需要恢复状态,在保存状态之后的 commit() 将会丢失,这和调用的初衷不符,所以会报错
**提示:**调用commit()方法并不立即执行这个事务,而是在Activity的UI线程之上(”main”线程)调度运行,以便这个线程能够尽快执行这个事务。但是,如果需要,可以调用来自UI线程的executePendingTransactions()方法,直接执行被commit()方法提交的事务。通常直到事务依赖其他线程的工作时才需要这样做
9,commitAllowingStateLoss() 也是异步执行,但它的不同之处在于,允许在 Activity 保存状态之后调用,也就是说它遇到状态丢失不会报错
10,commitNow() 是同步执行的,立即提交任务。前面提到 FragmentManager.executePendingTransactions() 也可以实现立即提交事务。但我们一般建议使用 commitNow(), 因为另外那位是一下子执行所有待执行的任务,可能会把当前所有的事务都一下子执行了,这有可能有副作用
11,addToBackStack():将本次提交事务添加到回退栈中

FragmentManager的队列、回退栈
通过transaction.addToBackStack(null)每次提交的改变组合叫做一个事务,每个事务被保存到Activity管理的回退堆栈中,并允许用户通过Fragment改变来向后导航,如果给事务添加多个改变(如用add()或remove()方法),并且调用了addToBackStack()方法,那么所有这些改变在调用commit()方法之前,都会作为一个单一的事务被添加到回退堆栈中,并且按返回按钮时,所有这些改变将会被恢复
提示:对于每个Fragment事务,你能够在提交之前通过调用setTransition()方法,申请一个过渡动画。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值