Mau*_*ker 4 android android-fragments kotlin material-design bottomnavigationview
我BottomNavigationView
在自己的一个活动中使用了Android设计支持库中的,同时在每个导航项中都使用了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()
}
Run Code Online (Sandbox Code Playgroud)
问题是...底部小节动画变得超级滞后,并且仅在片段完全加载并显示在屏幕上之后才能完成。
这个问题并不完全是新问题,因为在使用“导航菜单”时也可能发生,但是至少可以通过使用来解决它,DrawerLayout.DrawerListener
并且只有在抽屉关闭后才进行实际的Fragment事务。
我试图“缓存”片段,保留它们的引用以避免每次都重新创建对象(例如MyFragment.newInstance()
),但这是行不通的。
我也尝试使用处理程序,这可以解决问题,但是在某些情况下可能会导致异常。类似于以下代码段:
handler.postDelayed({changeFragment(fragmentToSet!!)}, 200)
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以解决此问题,而无需使用处理程序(或其他异步调用),方法与使用导航菜单时的解决方案类似?
我通过使用片段管理器隐藏和显示片段来处理这种情况。我编写了一个示例代码来处理它,如下所示。
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,
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1387 次 |
最近记录: |