我正在将我的应用程序更新为“导航体系结构组件”,我发现它具有替换片段的滞后性,这在导航抽屉中可见,但无法顺利关闭。
直到现在,我一直在使用这种方法:
https://vikrammnit.wordpress.com/2016/03/28/facing-navigation-drawer-item-onclick-lag/
因此,我在onDrawerClosed
中导航,而不是在onNavigationItemSelected
中导航,以避免出现故障。
这是一个非常普遍的问题,但是又回来了。使用导航组件时,它又很笨拙,我看不到在onDrawerClosed
中实现它的方法。
这些是导航组件之前的一些较早的答案
Navigation Drawer lag on Android
DrawerLayout's item click - When is the right time to replace fragment?
非常感谢您。
答案 0 :(得分:6)
在撰写此答案时,我正在解决此问题。经过一些测试,我得出的结论是我正在创建的片段中立即执行的代码(例如初始化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()
}
}
}
可以通过共享视图模型实现类似的解决方案。
答案 1 :(得分:0)
避免在NavigationItemSelected- Android上更改Fragment / Activity时引起的延迟
导航抽屉是应用程序中最常用的选项,当我们有五个以上的选项时,我们进入导航菜单。
我已经在许多应用程序中看到,当我们从导航菜单中更改选项时,我们发现它滞后了,StackOverflow上的一些人建议像下面的代码一样使用Handler:
private void openDrawerActivity(final Class className) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
ProjectUtils.genericIntent(NewDrawer.this, className, null, false);
}
}, 200);
}
但是在上面的代码中,它仍然不是很平滑,我想为什么我们要添加处理程序,可能是经过如此多的研发之后还有另一种解决方案,我发现我们需要在抽屉移动时更改片段/活动接近。让我们来看看实施。
有关解决方案的更多详细信息,请通过https://android.jlelse.eu/avoid-the-lag-caused-while-changing-fragment-activity-onnavigationitemselected-android-28bcb2528ad8。确实有帮助和有用。
希望您能找到更好的解决方案!