[Android] NavigationUI + BottomNavigationView 教學
簡介
Navigation Component 導入了 NavigationUI。通過這篇文章,我們來看看如何使用 NavigationUI 來對App bar和頁面切換進行管理。
教學
創建專案
創建專案並選擇 BottomNavigationActivity,目前官方提供的 Sample Code 都已經套用 NavigationUI,可方便建置。
建置內容
main_navigation.xml
此檔案內容負責管理 Fragment 的互動以及跳轉。
<navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main_navigation" app:startdestination="@id/navigation_index">
<fragment android:id="@+id/navigation_index" android:name="com.jim.covenantbible.view.IndexFragment" android:label="@string/index_title" tools:layout="@layout/fragment_index">
</fragment></navigation>
bottomnavmenu.xml
此檔案為設定 BottomNavigationView 的項目
<!--xml version="1.0" encoding="utf-8"?-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/navigation_index" android:icon="@drawable/icon_drawer_index" android:title="@string/index_title">
</item></menu>
activity_base.xml
其中使用 CoordinatorLayout 並包含 AppBarLayout (Toolbar)、FragmentContainerView、BottomNavigationView,以下再來細分說明各元件的用途。
- AppBarLayout (Toolbar):為 App 的 Top Action Bar。
- app:layout_scrollFlags:可實現滑動隱藏 Toolbar。
<com.google.android.material.appbar.appbarlayout style="@style/Widget.Material3.AppBarLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:fitssystemwindows="true">
<com.google.android.material.appbar.materialtoolbar android:id="@+id/toolbar" style="@style/TopAppBarTheme" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:contentinsetstart="0dp" app:layout_scrollflags="scroll|enterAlways|snap" app:titlemarginstart="16dp">
</com.google.android.material.appbar.materialtoolbar></com.google.android.material.appbar.appbarlayout>
- FragmentContainerView:為 Fragment 顯示的主區塊
- app:layout_scrollFlags:須設定此項目才可與 Toolbar 組合實現滑動隱藏 Toolbar。
- app:navGraph:指定Navigation Graph的xml檔。
<androidx.fragment.app.fragmentcontainerview android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultnavhost="true" app:layout_behavior="@string/appbar_scrolling_view_behavior" app:navgraph="@navigation/main_navigation">
- BottomNavigationView:為 Bottom Bar 的主體。
- app:layout_behavior:可實現滑動隱藏 BottomNavigationView。
- app:menu:指定 Bottom Bar 項目。
<com.google.android.material.bottomnavigation.bottomnavigationview android:id="@+id/nav_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom|start" android:background="?android:attr/windowBackground" app:labelvisibilitymode="labeled" app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior" app:menu="@menu/bottom_nav_menu">
BaseActivity.kt
class BaseActivity : AppCompatActivity() {
lateinit var binding: ActivityBaseBinding
private var nowSelectedPageID: Int? = 0
//region System Function
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityBaseBinding.inflate(layoutInflater)
setContentView(binding.root)
this.initNavigation()
}
//endregion
//region NavigateUI Function
/**
* set Fragment Navigation
* @menu/bottom_nav_menu: 底部 Navigation bar
* @navigation/main_navigation:主要控管 Fragment 的 Host Navigation
*/
private fun initNavigation() {
val navController = (supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment).navController.apply {
this.addOnDestinationChangedListener { _, destination, _ ->
if (this@BaseActivity.nowSelectedPageID == destination.id) {
return@addOnDestinationChangedListener
}
this@BaseActivity.nowSelectedPageID = destination.id
when (destination.id) {
R.id.navigation_index -> {
binding.navView.visibility = View.VISIBLE
binding.btnClickLeft.visibility = View.GONE
binding.btnClickRight.visibility = View.GONE
}
else -> {
binding.navView.visibility = View.GONE
binding.btnClickLeft.visibility = View.GONE
binding.btnClickRight.visibility = View.GONE
}
}
}
}
setSupportActionBar(binding.toolbar)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(setOf(R.id.navigation_index))
setupActionBarWithNavController(navController, appBarConfiguration)
binding.navView.setupWithNavController(navController)
}
/**
* if using setupActionBarWithNavController then also override and config this methods
*/
override fun onSupportNavigateUp(): Boolean {
val navController = (supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment).navController
return navController.navigateUp() || super.onSupportNavigateUp()
}
fun changeBottomNavigationViewItem(pageID: Int) {
this.binding.navView.selectedItemId = pageID
}
//endregion
}
留言
張貼留言