使用Navigation结合底部导航栏实现fragment切换

简介

关于通过google官方提供的Navigation实现fragment切换,之前已经写了一篇《使用Navigation简化fragment切换》。本文继续深入,结合底部导航栏实现fragment切换. 本文参考了google官网提供的一个demo,本文基于该demo优化过部分内容.

实现效果

使用Navigation结合底部导航栏实现fragment切换_第1张图片

使用方法

  1. 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"
  1. 添加navigation文件
  • nav_first.xml


   

  1. nav_second.xml


    

  1. 添加底部菜单文件:bottom_nav.xml

    
    

  1. 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一样.
使用Navigation结合底部导航栏实现fragment切换_第2张图片

如何增加一个菜单项

  1. 增加Fragment(ThirdFragment)及对应的布局文件(fragment_third.xml)
  2. 仿造nav_first.xml增加navigation文件nav_third.xml


    

  1. 在底部菜单bottom_nav.xml中增加菜单项

  1. 修改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
}
  1. 修改后效果
    使用Navigation结合底部导航栏实现fragment切换_第3张图片

源代码

https://gitee.com/cxyzy1/navigationDemo/tree/master/bottomNavigationView

附录

  1. navigation官方介绍文档:
    https://codelabs.developers.google.com/codelabs/android-navigation/#0
  2. google官网demo:
    https://github.com/googlesamples/android-architecture-components/tree/master/NavigationAdvancedSample
  3. 另外一种在navigation中实现fragment复用的方法(第三方提供的,较为复杂一些):
    https://github.com/STAR-ZERO/navigation-keep-fragment-sample.git

安卓开发技术分享: https://blog.csdn.net/yinxing2008/article/details/84555061
更多技术总结好文,请关注:「程序园中猿」

你可能感兴趣的:(安卓)