使用 Android Jetpack Navigation 组件和 Android BottomAppBar
Using Android Jetpack Navigation component with Android BottomAppBar
我正在尝试使用新的 Android 底部应用栏在我的 activity 中实现 Jetpack Navigation,但它没有正常工作。
我已经阅读了关于导航的说明,但似乎没有找到任何方法将导航 Jetpack 集成到新的底部应用栏中。我尝试按照以下方式进行操作:
我正在使用内部有 4 个片段的 Activity 在底部应用栏的导航抽屉中导航。
当我点击这个时预期的输出应该是:
Menu Icon
它应该像这样打开一个抽屉:
Bottom Drawer Navigation
而且我应该能够在片段之间导航。
但是,当我使用下面的代码时
activity_home.xml
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/myNavHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/bottomappbar_navigation" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottom_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:fabAlignmentMode="center"
app:navigationIcon="@drawable/ic_menu_dark"
app:menu="@menu/bottomappbar_main_menu"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_add_black"
android:backgroundTint="@color/colorAccent"
app:layout_anchor="@id/bottom_app_bar"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
导航文件是:
bottomappbar_navigation.xml
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bottomappbar_navigation" app:startDestination="@id/fragmentGoals">
<fragment
android:id="@+id/fragmentGoals"
android:name="com.th3pl4gu3.lifestyle.ui.FragmentGoals"
android:label="FragmentGoals"/>
<fragment
android:id="@+id/fragmentToDo"
android:name="com.th3pl4gu3.lifestyle.ui.FragmentToDo"
android:label="FragmentToDo"/>
<fragment
android:id="@+id/fragmentToBuy"
android:name="com.th3pl4gu3.lifestyle.ui.FragmentToBuy"
android:label="FragmentToBuy"/>
<fragment
android:id="@+id/fragmentStatistics"
android:name="com.th3pl4gu3.lifestyle.ui.FragmentStatistics"
android:label="FragmentStatistics"/>
</navigation>
bottomappbar_drawer_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:checkableBehavior="single">
<item
android:id="@+id/fragmentGoals"
android:icon="@drawable/ic_add_black"
android:title="Goals"/>
<item
android:id="@+id/fragmentToDo"
android:icon="@drawable/ic_add_black"
android:title="To Do"/>
<item
android:id="@+id/fragmentToBuy"
android:icon="@drawable/ic_add_black"
android:title="To Buy"/>
<item
android:id="@+id/fragmentStatistics"
android:icon="@drawable/ic_add_black"
android:title="Statistics"/>
</group>
</menu>
bottomappbar_main_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/search"
android:title="Search"
android:icon="@drawable/ic_search_black"
app:showAsAction="always"
android:tooltipText="Search" />
</menu>
然后在我的 ActivityHome.kt:
class ActivityHome : AppCompatActivity() {
private lateinit var mBinding: ActivityHomeBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_home)
setSupportActionBar(mBinding.bottomAppBar)
val navController = Navigation.findNavController(this, R.id.myNavHostFragment)
mBinding.bottomAppBar.setupWithNavController(navController)
mBinding.bottomAppBar.setOnMenuItemClickListener { menuItem ->
menuItem.onNavDestinationSelected(navController)
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.bottomappbar_main_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when(item?.itemId){
R.id.search -> {Toast.makeText(this, "Search clicked!", Toast.LENGTH_SHORT).show()}
}
return true
}
}
底部应用栏上的菜单图标消失了,如下所示:
Output
我想我没有正确使用 Jetpack Navigation。
能否请您提供 link 或一些有关如何实现此功能的代码?
更改您的 activity 和布局如下
主要活动
class MainActivity : AppCompatActivity() {
private lateinit var mBinding: ActivityHomeBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_home)
val navController = Navigation.findNavController(this, R.id.navFragment)
mBinding.navigationView.setupWithNavController(navController)
setSupportActionBar(mBinding.bottomAppBar)
if (mBinding.navigationView.isShown) {
mBinding.navigationView.visibility = View.VISIBLE
} else {
mBinding.navigationView.visibility = View.GONE
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.bottomappbar_main_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when(item?.itemId){
android.R.id.home -> {
Log.e("TAG", "Visbility>>>> ${mBinding.navigationView.isShown}")
if (!mBinding.navigationView.isShown) {
mBinding.navigationView.visibility = View.VISIBLE
} else {
mBinding.navigationView.visibility = View.GONE
}
}
R.id.search -> {
Toast.makeText(this, "Search clicked!", Toast.LENGTH_SHORT).show()
}
}
return true
}
}
activity_home.xml
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/navFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"
android:layout_marginBottom="60dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottom_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:fabAlignmentMode="center"
style="@style/Widget.MaterialComponents.BottomAppBar"
app:menu="@menu/bottomappbar_main_menu"
android:backgroundTint="@color/colorPrimaryDark"
app:navigationIcon="@drawable/ic_menu_dark"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_add_black"
android:backgroundTint="@color/colorAccent"
app:layout_anchor="@id/bottom_app_bar"/>
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="@id/bottom_app_bar"
android:background="@android:color/white"
android:layout_gravity="start"
app:menu="@menu/bottomappbar_drawer_menu"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</RelativeLayout>
我正在尝试使用新的 Android 底部应用栏在我的 activity 中实现 Jetpack Navigation,但它没有正常工作。
我已经阅读了关于导航的说明,但似乎没有找到任何方法将导航 Jetpack 集成到新的底部应用栏中。我尝试按照以下方式进行操作:
我正在使用内部有 4 个片段的 Activity 在底部应用栏的导航抽屉中导航。
当我点击这个时预期的输出应该是:
Menu Icon
它应该像这样打开一个抽屉:
Bottom Drawer Navigation
而且我应该能够在片段之间导航。
但是,当我使用下面的代码时
activity_home.xml
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/myNavHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/bottomappbar_navigation" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottom_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:fabAlignmentMode="center"
app:navigationIcon="@drawable/ic_menu_dark"
app:menu="@menu/bottomappbar_main_menu"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_add_black"
android:backgroundTint="@color/colorAccent"
app:layout_anchor="@id/bottom_app_bar"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
导航文件是:
bottomappbar_navigation.xml
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bottomappbar_navigation" app:startDestination="@id/fragmentGoals">
<fragment
android:id="@+id/fragmentGoals"
android:name="com.th3pl4gu3.lifestyle.ui.FragmentGoals"
android:label="FragmentGoals"/>
<fragment
android:id="@+id/fragmentToDo"
android:name="com.th3pl4gu3.lifestyle.ui.FragmentToDo"
android:label="FragmentToDo"/>
<fragment
android:id="@+id/fragmentToBuy"
android:name="com.th3pl4gu3.lifestyle.ui.FragmentToBuy"
android:label="FragmentToBuy"/>
<fragment
android:id="@+id/fragmentStatistics"
android:name="com.th3pl4gu3.lifestyle.ui.FragmentStatistics"
android:label="FragmentStatistics"/>
</navigation>
bottomappbar_drawer_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:checkableBehavior="single">
<item
android:id="@+id/fragmentGoals"
android:icon="@drawable/ic_add_black"
android:title="Goals"/>
<item
android:id="@+id/fragmentToDo"
android:icon="@drawable/ic_add_black"
android:title="To Do"/>
<item
android:id="@+id/fragmentToBuy"
android:icon="@drawable/ic_add_black"
android:title="To Buy"/>
<item
android:id="@+id/fragmentStatistics"
android:icon="@drawable/ic_add_black"
android:title="Statistics"/>
</group>
</menu>
bottomappbar_main_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/search"
android:title="Search"
android:icon="@drawable/ic_search_black"
app:showAsAction="always"
android:tooltipText="Search" />
</menu>
然后在我的 ActivityHome.kt:
class ActivityHome : AppCompatActivity() {
private lateinit var mBinding: ActivityHomeBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_home)
setSupportActionBar(mBinding.bottomAppBar)
val navController = Navigation.findNavController(this, R.id.myNavHostFragment)
mBinding.bottomAppBar.setupWithNavController(navController)
mBinding.bottomAppBar.setOnMenuItemClickListener { menuItem ->
menuItem.onNavDestinationSelected(navController)
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.bottomappbar_main_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when(item?.itemId){
R.id.search -> {Toast.makeText(this, "Search clicked!", Toast.LENGTH_SHORT).show()}
}
return true
}
}
底部应用栏上的菜单图标消失了,如下所示:
Output
我想我没有正确使用 Jetpack Navigation。
能否请您提供 link 或一些有关如何实现此功能的代码?
更改您的 activity 和布局如下
主要活动
class MainActivity : AppCompatActivity() {
private lateinit var mBinding: ActivityHomeBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_home)
val navController = Navigation.findNavController(this, R.id.navFragment)
mBinding.navigationView.setupWithNavController(navController)
setSupportActionBar(mBinding.bottomAppBar)
if (mBinding.navigationView.isShown) {
mBinding.navigationView.visibility = View.VISIBLE
} else {
mBinding.navigationView.visibility = View.GONE
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.bottomappbar_main_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when(item?.itemId){
android.R.id.home -> {
Log.e("TAG", "Visbility>>>> ${mBinding.navigationView.isShown}")
if (!mBinding.navigationView.isShown) {
mBinding.navigationView.visibility = View.VISIBLE
} else {
mBinding.navigationView.visibility = View.GONE
}
}
R.id.search -> {
Toast.makeText(this, "Search clicked!", Toast.LENGTH_SHORT).show()
}
}
return true
}
}
activity_home.xml
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/navFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"
android:layout_marginBottom="60dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottom_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:fabAlignmentMode="center"
style="@style/Widget.MaterialComponents.BottomAppBar"
app:menu="@menu/bottomappbar_main_menu"
android:backgroundTint="@color/colorPrimaryDark"
app:navigationIcon="@drawable/ic_menu_dark"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_add_black"
android:backgroundTint="@color/colorAccent"
app:layout_anchor="@id/bottom_app_bar"/>
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="@id/bottom_app_bar"
android:background="@android:color/white"
android:layout_gravity="start"
app:menu="@menu/bottomappbar_drawer_menu"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</RelativeLayout>