简介
关于通过google官方提供的Navigation实现fragment切换,之前已经写了一篇《使用Navigation简化fragment切换》。本文继续深入,结合底部导航栏实现fragment切换. 本文参考了google官网提供的一个demo,本文基于该demo优化过部分内容.
实现效果- build.gradle中添加依赖
implementation "android.arch.navigation:navigation-common-ktx:1.0.0"
implementation "android.arch.navigation:navigation-fragment-ktx:1.0.0"
implementation "android.arch.navigation:navigation-runtime-ktx:1.0.0"
implementation "android.arch.navigation:navigation-ui-ktx:1.0.0"
- 添加navigation文件
- nav_first.xml
- nav_second.xml
- 添加底部菜单文件:bottom_nav.xml
- MainActivity (下面代码中的setupWithNavController是扩展的自定义函数,请查看Demo源代码下载)
class MainActivity : AppCompatActivity() {
private var currentNavController: LiveData? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
setupBottomNavigationBar()
}
}
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
super.onRestoreInstanceState(savedInstanceState)
setupBottomNavigationBar()
}
private fun setupBottomNavigationBar() {
val bottomNavigationView = findViewById(R.id.bottom_nav)
val navGraphIds = listOf(R.navigation.nav_first, R.navigation.nav_second)
// Setup the bottom navigation view with a list of navigation graphs
val controller = bottomNavigationView.setupWithNavController(
navGraphIds = navGraphIds,
fragmentManager = supportFragmentManager,
containerId = R.id.nav_host_container,
intent = intent,
listener = mOnNavigationItemSelectedListener
)
// Whenever the selected controller changes, setup the action bar.
controller.observe(this, Observer { navController ->
setupActionBarWithNavController(navController)
})
currentNavController = controller
}
/**
* Define your own listener for bottom navigation item clicking.
*/
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.nav_first -> {
Toast.makeText(this@MainActivity, "firstFragment", Toast.LENGTH_SHORT).show()
return@OnNavigationItemSelectedListener true
}
R.id.nav_second -> {
Toast.makeText(this@MainActivity, "secondFragment", Toast.LENGTH_SHORT).show()
return@OnNavigationItemSelectedListener true
}
}
true
}
override fun onSupportNavigateUp(): Boolean {
return currentNavController?.value?.navigateUp() ?: false
}
/**
* Overriding popBackStack is necessary in this case if the app is started from the deep link.
*/
override fun onBackPressed() {
if (currentNavController?.value?.popBackStack() != true) {
super.onBackPressed()
}
}
}
代码说明
底部菜单项和Fragment的对应关系如下图,menu的item的id需要和导航文件中navigation的id一样.
- 增加Fragment(ThirdFragment)及对应的布局文件(fragment_third.xml)
- 仿造nav_first.xml增加navigation文件nav_third.xml
- 在底部菜单bottom_nav.xml中增加菜单项
- 修改MainActivity
- 修改setupBottomNavigationBar函数 由
val navGraphIds = listOf(R.navigation.nav_first, R.navigation.nav_second)
修改为val navGraphIds = listOf(R.navigation.nav_first, R.navigation.nav_second,R.navigation.nav_third)
- 修改mOnNavigationItemSelectedListener 增加
R.id.nav_third -> {
Toast.makeText(this@MainActivity, "thirdFragment", Toast.LENGTH_SHORT).show()
return@OnNavigationItemSelectedListener true
}
- 修改后效果
https://gitee.com/cxyzy1/navigationDemo/tree/master/bottomNavigationView
附录- navigation官方介绍文档: https://codelabs.developers.google.com/codelabs/android-navigation/#0
- google官网demo: https://github.com/googlesamples/android-architecture-components/tree/master/NavigationAdvancedSample
- 另外一种在navigation中实现fragment复用的方法(第三方提供的,较为复杂一些): https://github.com/STAR-ZERO/navigation-keep-fragment-sample.git
厦门大学计算机专业 | 前华为工程师 Java | 安卓 | 前端 | 小程序 | 鸿蒙 公众号:蓝不蓝编程