今天在实践androidX的fragment懒加载方案的时候,又复习了一下fragment的切换。以前没有时间记下来,今天就记录一下吧。
1、使用replace切换fragment
我们都知道我们在同一个FrgmentLayout中切换不同的fragment的时候,我们可以直接用replace,那么用replace的时候,我们之前加进去的fragment是什么状态呢。下面我们实践一下。
private fun changeFragment(index: Int) {
ft = fm.beginTransaction()
var currentFragmnet:Fragment? = null
when (index) {
0 -> {
if (oneFragment == null){
oneFragment = OneFragment()
}
currentFragmnet = oneFragment as OneFragment
}
1 -> {
if (twoFragment == null){
twoFragment = TwoFragment()
}
currentFragmnet = twoFragment as TwoFragment
}
2 -> {
if (threeFragment == null){
threeFragment = ThreeFragment()
}
currentFragmnet = threeFragment as ThreeFragment
}
}
if (currentFragmnet == null){
currentFragmnet = OneFragment()
}
ft.replace(mDataBinding.flFragment.id,currentFragmnet).commit()
}
我在界面上设置了三个按钮,然后对应创建了三个fragment。先看看当首次进入页面,加入第一个fragment的时候生命周期是什么样子的
这是一个正常显示fragment的生命周期,然后我在切换到第二个fragment,查看生命周期的改变
可以看到上一个显示的fragment是被销毁了的,然后创建显示了第二个fragment,然后再切换会第一个fragment,查看生命周期变化,
可以很清楚的看到,第二个fragment被销毁移除,然后新建了第一个fragment。所以我们使用replace的时候,实际上就等同于我们把之前一个fragment移除了,然后add了一个新的fragment。验证一下我们实践一下,add和remove:
private fun changeFragmentRemoveAndAdd(index: Int) {
ft = fm.beginTransaction()
when (index) {
0 -> {
if (oneFragment == null){
oneFragment = OneFragment()
}
ft.add(mDataBinding.flFragment.id, oneFragment!!)
if (twoFragment != null){
ft.remove(twoFragment!!)
}
if (threeFragment!=null){
ft.remove(threeFragment!!)
}
}
1 -> {
if (twoFragment == null){
twoFragment = TwoFragment()
}
ft.add(mDataBinding.flFragment.id, twoFragment!!)
if (oneFragment != null){
ft.remove(oneFragment!!)
}
if (threeFragment!=null){
ft.remove(threeFragment!!)
}
}
2 -> {
if (threeFragment == null){
threeFragment = ThreeFragment()
}
ft.add(mDataBinding.flFragment.id, threeFragment!!)
if (twoFragment != null){
ft.remove(twoFragment!!)
}
if (oneFragment!=null){
ft.remove(oneFragment!!)
}
}
}
ft.commit()
}
先看加入第一个fragment的时候的生命周期:
这个没什么好说的,第一个加入生命周期肯定都是一样的,直接看切换的时候的生命周期:
可以看到和replace是一样的,然后再切换会第一个fragment:
切换回来生命周期也是一样的。如果我们在切换fragment的时候想要不保留之前的显示的状态,我们就可以把之前的fragment remove掉然后添加我们想要的新fragment。我觉得还是用replace比add+remove方便多了。但是有的时候我们想要保留之前的fragment状态,这个时候我们就不能去remove和add了,我们应该要show和hidden。如下:
private fun changeFragmentShowAndHidden(index: Int) {
ft = fm.beginTransaction()
when (index) {
0 -> {
if (oneFragment == null){
oneFragment = OneFragment()
ft.add(mDataBinding.flFragment.id, oneFragment!!)
}else {
ft.show(oneFragment!!)
}
if (twoFragment != null){
ft.hide(twoFragment!!)
}
if (threeFragment!=null){
ft.hide(threeFragment!!)
}
}
1 -> {
if (twoFragment == null){
twoFragment = TwoFragment()
ft.add(mDataBinding.flFragment.id, twoFragment!!)
}else{
ft.show(twoFragment!!)
}
if (oneFragment != null){
ft.hide(oneFragment!!)
}
if (threeFragment!=null){
ft.hide(threeFragment!!)
}
}
2 -> {
if (threeFragment == null){
threeFragment = ThreeFragment()
ft.add(mDataBinding.flFragment.id, threeFragment!!)
}else{
ft.show(threeFragment!!)
}
if (twoFragment != null){
ft.hide(twoFragment!!)
}
if (oneFragment!=null){
ft.hide(oneFragment!!)
}
}
}
ft.commit()
}
首次进入的时候是添加一个onefragment,生命周期就是正常的创建
切换到twoFragment:
切换回onefragment:
!!!生命周期没有返回任何改变。
所以这个时候我们的fragment 除了对用户可见状态发生了改变,生命周期是没有受任何影响的。
综上所诉,我们可以根据我们自己的需求,去选择使用什么样子的方式切换fragment