问题 我在我的一个活动中使用Android设计支持库中的BottomNavigationView,以及每个导航项的Fragments. 每次我在栏上选择一个项目时,我都会进行片段交易,就像下面的片段一样(为简洁起见,代码
我在我的一个活动中使用Android设计支持库中的BottomNavigationView,以及每个导航项的Fragments.
每次我在栏上选择一个项目时,我都会进行片段交易,就像下面的片段一样(为简洁起见,代码的某些部分被删除):
private var fragmentToSet: Fragment? = null private val onNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> fragmentToSet = when (item.itemId) { // Choose fragment based on selection // ... } // ... supportFragmentManager.beginTransaction() .replace(R.id.container, fragmentToSet) .commit() }
问题是……底栏动画变得超级滞后,只有在片段完全加载并在屏幕上显示后才能完成.
这个问题is not exactly new因为它也可以在使用导航菜单时发生,但至少可以通过使用DrawerLayout.DrawerListener来解决它并仅在抽屉关闭后进行实际的Fragment事务.
到目前为止我尝试过的
我试图“缓存”片段,保留它们的引用以避免每次都重新创建对象(例如MyFragment.newInstance()),但这不起作用.
我也尝试使用处理程序,这有点解决了这个问题,但它可能会导致我遇到异常in some cases.类似下面的代码片段:
handler.postDelayed({changeFragment(fragmentToSet!!)}, 200)
有没有办法在不使用处理程序(或其他异步调用)的情况下解决此问题,在使用导航菜单时与this solution类似?
我通过使用片段管理器隐藏和显示片段来处理这种情况.我写了一个示例代码来处理它,如下所示.class MainActivity : BaseActivity() { private val homeFragment = HomeFragment.newInstance() private val categoryFragment = CategoryFragment.newInstance() private val searchFragment = SearchFragment.newInstance() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) navigation.menu.findItem(R.id.navigation_home).isChecked = true supportFragmentManager.beginTransaction() .add(R.id.containerFrameLayout, homeFragment) .add(R.id.containerFrameLayout, categoryFragment) .add(R.id.containerFrameLayout, searchFragment) .commit() setTabStateFragment(TabState.HOME).commit() } override fun onBackPressed() { if (supportFragmentManager.backStackEntryCount > 0 || !homeFragment.isHidden) { super.onBackPressed() } else { setTabStateFragment(TabState.HOME).commit() navigation.menu.findItem(R.id.navigation_home).isChecked = true } } private fun setTabStateFragment(state: TabState): FragmentTransaction { supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) val transaction = supportFragmentManager.beginTransaction() transaction.setCustomAnimations(R.anim.fragment_enter, R.anim.fragment_exit) when (state) { TabState.HOME -> { transaction.show(homeFragment) transaction.hide(categoryFragment) transaction.hide(searchFragment) } TabState.CATEGORY -> { transaction.hide(homeFragment) transaction.show(categoryFragment) transaction.hide(searchFragment) } TabState.SEARCH -> { transaction.hide(homeFragment) transaction.hide(categoryFragment) transaction.show(searchFragment) } } return transaction } private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> when (item.itemId) { R.id.navigation_home -> { setTabStateFragment(TabState.HOME).commit() return@OnNavigationItemSelectedListener true } R.id.navigation_category -> { setTabStateFragment(TabState.CATEGORY).commit() return@OnNavigationItemSelectedListener true } R.id.navigation_search -> { setTabStateFragment(TabState.SEARCH).commit() return@OnNavigationItemSelectedListener true } } false } internal enum class TabState { HOME, CATEGORY, SEARCH, } }