此Bug可能不符合其他需求哦,仅限个人总结;
界面描述:MainActivity用tablayout+viewpager2实现了首页五个Fragment横向切换,然后在第四个FourthFragment里,实现了Viewpager2的类似于画廊的多个ChatFragment纵向切换。
问题描述:
1.我在Main页面,进行Tab切换到FourthFragment时,FourthFragment调用onResume方法(正常的),但是其正在展示的ChatFragment并没有调用onResume方法。
期望结果:ChatFragment调用onResume,因为我需要刷新最新的数据,或者进行一些操作
2.我在Main页面的非FourthFragment页面进入二级页面回来后,FourthFragment没有调用onResume方法(正常的),但是FourthFragment的Viewpager2里的当前ChatFragment调用了onResume方法。
期望结果:FourthFragment没有调用,里面的也不要调用,外层Fragment和内层Fragment统一。
解决办法:
1.符合自己需求的解决办法
在FourthFragment
override fun onResume() {
super.onResume()
if (curFragment != null) {
curFragment?.setParentVisible(true)
curFragment?.onResume()
}
}
override fun onPause() {
super.onPause()
if (curFragment != null) {
curFragment?.setParentVisible(false)
curFragment?.onPause()
}
}
在ChatFragment
private var hasPlayedAudio = false
private var isParenVisible = true
fun setParentVisible(isVisible: Boolean) {
isParenVisible = isVisible
}
override fun onResume() {
super.onResume()
if (!isParenVisible) return
if (isFirst) {
isFirst = false
return
}
LogUtils.e("AAA", "onResume: ${chatAdapter.messages.size}")
......
//自己的操作逻辑,我主要是播放音频
}
override fun onPause() {
super.onPause()
chatAdapter.stopAudio()
hasPlayedAudio = false
}
这样就保证了,以父FourthFragment为优先判断的统一生命周期的方法。
下面是其他的方法,不太符合我的需求,所以我当时用起来有时候失灵,但是也写下来吧
2.其余方法
方法 1:使用 ViewPager2 + FragmentTransaction
适用于: ViewPager2
,官方推荐的方法,最稳定。例如MainAc里控制展示的五个Fragment的状态
在 ViewPager2
里,官方推荐使用 FragmentTransaction
控制 Fragment
的 setMaxLifecycle()
,保证只有当前可见的 Fragment
进入 RESUMED 状态:
val adapter = object : FragmentStateAdapter(this) {
override fun getItemCount(): Int = fragments.size
override fun createFragment(position: Int): Fragment = fragments[position]
}
viewPager2.adapter = adapter
// 让只有当前 Fragment 进入 RESUMED 状态,其他 Fragment 停留在 STARTED
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
val fragment = fragments[position]
supportFragmentManager.beginTransaction()
.setMaxLifecycle(fragment, Lifecycle.State.RESUMED)
.commit()
}
})
方法 2:在 onResume()
里判断是否可见
适用于: ViewPager
(非 ViewPager2
),但可能会有一定的性能损耗。
class MyFragment : Fragment() {
private var isViewCreated = false
private var isVisibleToUser = false
override fun onResume() {
super.onResume()
if (isVisibleToUser && isViewCreated) {
loadData()
}
}
override fun onPause() {
super.onPause()
isVisibleToUser = false
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
this.isVisibleToUser = isVisibleToUser
if (isVisibleToUser && isResumed && isViewCreated) {
loadData()
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
isViewCreated = true
}
private fun loadData() {
// 你的网络请求代码
}
}