我在撰写此答案时正在解决此问题。经过一些测试,我得出结论:在创建片段后的片段中执行的代码(例如初始化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
configureUI()
}
}
}
可以通过共享视图模型来实现类似的解决方案。
onDrawerClosed
并使用NavController
类和.navigate(..)
方法来放置片段导航逻辑。这是我所知道的全部内容。 - Michael Zur