首先为什么会写这篇文章呢 是因为自己在学习仿抖音效果上下滑动播放视频的时候发现
切换fragment 的时候发现 onHiddenChanged 以及生命周期都不走 后来发现自己基础知识不够
查询才知道fragment 嵌套 viewpager fragment 这种组合方式 切换fragment 生命周期不走 onHiddenChanged 也不走
走的是 setUserVisibleHint这个方法 而且 FragmentStatePagerAdapter 也添加了新的方法 旧的方法废弃了
public FragmentStatePagerAdapter(@NonNull FragmentManager fm,
@Behavior int behavior) {
mFragmentManager = fm;
mBehavior = behavior;
}
推荐使用这个方法 Behavior 有两个值 BEHAVIOR_SET_USER_VISIBLE_HINT 和BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
不过BEHAVIOR_SET_USER_VISIBLE_HINT 也废弃了 只能使用第二个值
这个方法切换fragment现在切换 显示的fragment 会走 onResume 隐藏的fragment 会走 onResume
setUserVisibleHint onHiddenChanged 方法都不会调用
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
tools:context=".ui.MainActivity">
<FrameLayout
android:id="@+id/mFrameLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/mBottomNavigation"
android:layout_width="match_parent"
android:layout_height="50dp"
app:menu="@menu/navigation"
app:labelVisibilityMode="labeled"
app:itemBackground="@color/colorWhite"/>
</LinearLayout>
首先activity下的布局使用的 BottomNavigationView 和 FrameLayout 总共两个fragment
private fun switchFragment(position: Int) {
val beginTransaction = supportFragmentManager.beginTransaction()
var fragment = fragments[position]
fragments.filter {
it.isAdded
}.forEach {
beginTransaction.hide(it)
}
if (fragment.isAdded) {
beginTransaction.show(fragment)
} else {
beginTransaction.add(R.id.mFrameLayout, fragment)
}
beginTransaction.commit()
}
fragment的切换显示生命周期
onAttach>onCreate>onCreateView>onActivityCreated>onStart>onResume
第二个fragment 还没用到所以就走了一次 当切换的时候 发现是 第二个的先走
onAttach>onCreate>然后走了第一个fragment onHiddenChanged: true 然后走的
onCreateView>onActivityCreated>onStart>onResume
之后切换两个fragment 都走onHiddenChanged 方法 页面退出 两个fragment都走
onPause>onStop>onDestroyView>onDestroy>onDetach 到此生命周期都走完
本来想fragment 弄个懒加载吧 发现 setUserVisibleHint 方法已过时刚才这个方法都没有调用官方推荐使用
/ *
* @deprecated Use {@link FragmentTransaction#setMaxLifecycle(Fragment, Lifecycle.State)}
* instead.
*/
@Deprecated
public void setUserVisibleHint(boolean isVisibleToUser) {
Lifecycle.State共有五种状态
CREATED LifecycleOwner的创建状态。
DESTROYED LifecycleOwner的已销毁状态。
INITIALIZED LifecycleOwner的初始化状态。
RESUMED LifecycleOwner的恢复状态。
STARTED LifecycleOwner的开始状态。
后来网上查询下 fragment的切换修改为如下代码
private fun switchFragment(position: Int) {
val beginTransaction = supportFragmentManager.beginTransaction()
var fragment = fragments[position]
fragments.filter {
it.isAdded
}.forEach {
beginTransaction.hide(it).setMaxLifecycle(it, Lifecycle.State.STARTED)
}
if (fragment.isAdded) {
beginTransaction.show(fragment).setMaxLifecycle(fragment, Lifecycle.State.RESUMED)
} else {
beginTransaction.add(R.id.mFrameLayout, fragment)
}
beginTransaction.commit()
}
生命周期有一点小变化 两个fragment都创建以后 以前都只会走onHiddenChanged 方法
现在切换 显示的fragment 会走 onHiddenChanged onResume
隐藏的fragment 会走onHiddenChanged onResume
最后说下如果发现有错误的地方欢迎指正
网友评论