Bug记录-Viewpager2的Fragment生命周期同步问题

此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 控制 FragmentsetMaxLifecycle(),保证只有当前可见的 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() {
        // 你的网络请求代码
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&岁月不待人&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值