我在写这个答案时正在解决这个问题。经过一些测试,我得出结论,我在创建片段后立即在片段中执行的代码(例如初始化 RecyclerView 适配器并用数据填充它,或配置 UI)导致抽屉滞后,因为这一切同时发生。
现在我得到的最好的想法类似于一些依赖onDrawerClosed 的旧解决方案。我们延迟片段中代码的执行,直到抽屉关闭。在抽屉关闭之前,片段的布局将变得可见,因此它仍然看起来快速且响应迅速。
请注意,我也在使用导航组件。
首先,我们将创建一个接口并实现它的片段。
interface StartFragmentListener {
fun configureFragment()
}
在活动设置 DrawerListener 中像:
private fun configureDrawerStateListener(){
psMainNavDrawerLayout.addDrawerListener(object: DrawerLayout.DrawerListener{
override fun onDrawerStateChanged(newState: Int) {}
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
override fun onDrawerOpened(drawerView: View) {}
override fun onDrawerClosed(drawerView: View) {
notifyDrawerClosed()
}
})
}
通知片段抽屉已关闭,它可以执行导致延迟的操作:
private fun notifyDrawerClosed(){
val currentFragment =
supportFragmentManager.findFragmentById(R.id.psMainNavHostFragment)
?.childFragmentManager?.primaryNavigationFragment
if(currentFragment is StartFragmentListenr && currentFragment != null)
currentFragment.configureFragment()
}
如果您没有从抽屉导航到片段(例如按下后退按钮),您还需要通知片段执行它的操作。我们将实现 FragmentLifecycleCallbacksListener:
private fun setupFragmentLifecycleCallbacksListener(){
supportFragmentManager.findFragmentById(R.id.psMainNavHostFragment)
?.childFragmentManager?.registerFragmentLifecycleCallbacks(object : FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentActivityCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) {
super.onFragmentActivityCreated(fm, f, savedInstanceState)
if (!psMainNavDrawerLayout.isDrawerOpen(GravityCompat.START)) {
if (f is StartFragmentListener)
f.configureFragment()
}
}
}, true)
}
在片段中:
class MyFragment: Fragment(), MyActivity.StartFragmentListener {
private var shouldConfigureUI = true
...
override fun onDetach() {
super.onDetach()
shouldConfigureUI = true
}
override fun configureFragment() {
if(shouldConfigureUI){
shouldConfigureUI = false
//do your things here, like configuring UI, getting data from VM etc...
configureUI()
}
}
}
可以使用共享视图模型实现类似的解决方案。