Kotlin中如何根据选中的Fragment显示/隐藏FloatingActionButton
问题原因
崩溃日志明确指向 kotlin.UninitializedPropertyAccessException: lateinit property binding has not been initialized,原因是Fragment的onCreateView生命周期执行时机早于Activity的binding初始化完成时机:Activity在onCreate中先inflate布局,布局里的NavHostFragment会直接触发默认首页Fragment的onCreateView,这时候Activity的binding还没完成赋值,你在Fragment的onCreateView里调用Activity的showFabOne就会访问还没初始化的binding,导致崩溃。
解决方案
方案1:修改Fragment调用方法的生命周期
把Fragment中调用showFabOne/hideFabOne的逻辑从onCreateView移到onResume中,此时Activity已经完成初始化,binding已经可用,不会再触发未初始化异常。
方案2(更推荐):Activity全局监听导航变化,统一控制FAB显隐
不用每个Fragment单独调用方法,直接在HomeActivity中监听导航目的地切换,自动控制FAB显隐,逻辑更集中,也完全规避生命周期时序问题:
在HomeActivity的onCreate方法中添加如下代码:
// 先完成binding初始化 binding = ActivityHomeBinding.inflate(layoutInflater) setContentView(binding.root) // 拿到NavController val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController // 监听导航目的地变化 navController.addOnDestinationChangedListener { _, destination, _ -> when(destination.id) { // 对应你导航图里fragment1、fragment2的id R.id.fragment1, R.id.fragment2 -> binding.fabOne.show() // 其他页面隐藏 else -> binding.fabOne.hide() } }
用这个方案你可以完全删掉Fragment里调用show/hide FAB的代码,所有控制逻辑都在Activity中统一处理,不会再出现时序问题。
内容的提问来源于stack exchange,提问作者Codist
相关产品推荐
相关产品推荐

