从0到1打造一款安卓app之8-使用BottomNavigationView+Navigation实现主页
1.activity_main.xml 和 bottom_nav.xml和导航图
layout-> activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/gray"
app:menu="@menu/bottom_nav"
app:itemActiveIndicatorStyle="@null"
app:itemBackground="@null"
app:itemRippleColor="@null"
app:itemTextColor="@color/item_icon_color_selector"
app:itemIconTint="@color/item_icon_color_selector"
app:itemTextAppearanceActive="@style/text_appearance_active_style"
app:itemTextAppearanceInactive="@style/text_appearance_inactive_style"
app:labelVisibilityMode="labeled"/>
</LinearLayout>
</layout>
app:labelVisibilityMode="labeled" 总是显示图标和文字
app:itemTextAppearanceActive="@style/text_appearance_active_style" 文本选中时样式,一般用于定义文本字体大小
app:itemTextAppearanceInactive="@style/text_appearance_inactive_style" 文本未选中时样式,一般用于定义文本字体大小
app:itemTextColor="@color/item_icon_color_selector"文本颜色,通过selector配置选中和未选中时的颜色
app:itemIconTint="@color/item_icon_color_selector" 图标颜色,(好像不生效)
app:itemActiveIndicatorStyle="@null" 去掉选中后图标的背景
app:itemBackground="@null" 去掉图标和文本选中后的背景
app:itemRippleColor="@null" 去掉图标和文本选中后的水波纹
app:menu="@menu/bottom_nav" 设置图标和文本
app:itemIconSize="22dp"设置图标大小,默认 24dp
app:itemPaddingTop="6dp" app:itemPaddingBottom="6dp" 设置上下内边距,默认 12dp,16dp
android:minHeight="50dp"设置高度,默认是80dp
android:background="@color/gray" 设置背景
menu -> bottom_nav.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/home"
android:icon="@drawable/ic_message_selector"
android:contentDescription="@string/home_message"
android:title="@string/home_message" />
<item
android:id="@+id/information"
android:icon="@drawable/ic_information_selector"
android:contentDescription="@string/home_information"
android:title="@string/home_information" />
<item
android:id="@+id/form"
android:icon="@drawable/ic_micro_blog_selector"
android:contentDescription="@string/home_micro_blog"
android:title="@string/home_micro_blog" />
<item
android:id="@+id/discover"
android:icon="@drawable/ic_discover_selector"
android:contentDescription="@string/home_discover"
android:title="@string/home_discover" />
<item
android:id="@+id/home_mine"
android:icon="@drawable/ic_mine_selector"
android:contentDescription="@string/home_mine"
android:title="@string/home_mine" />
</menu>
android:icon="@drawable/ic_message_selector"通过selector定义选中和未选中时的国标,实现不同的颜色和大小
导航图
<navigation
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph"
app:startDestination="@+id/main_message_nav_graph">
<include app:graph="@navigation/main_message_nav_graph"/>
<include app:graph="@navigation/main_information_nav_graph"/>
<include app:graph="@navigation/main_micro_blog_nav_graph"/>
<include app:graph="@navigation/main_discover_nav_graph"/>
<include app:graph="@navigation/main_mine_nav_graph"/>
<fragment
android:id="@+id/LoginScreen"
android:name="xxx.yyy.zzz.ui.fragments.LoginFragment"
android:label="@string/login">
</fragment>
</navigation>
2.设置未读数图标
getOrCreateBadge(R.id.home) //只显示一个红点
getOrCreateBadge(R.id.home).number = 10 //显示具体数字
bottomNavigationMenuView.removeBadge(menu.itemId)//清除未读效果
3.BottomNavigationView和NavController的关联
NavigationBarView.setupWithNavController(navController: NavController)方法可以把BottomNavigationView和NavController关联起来,当点击相应的MenuItem时,会自动导航到相应的fragment,前提是 menu->bottom_nav下的item的id要和导航图里的一样。
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_container) as NavHostFragment
navController = navHostFragment.navController.apply {
mainBinding.bottomNav.setupWithNavController(this)
}
}
实现点击到二级页面时,隐藏BottomNavigationView
addOnDestinationChangedListener { controller, destination, arguments ->
mainBinding.bottomNav.visibility = if (mainNavIds.contains(destination.id)) View.VISIBLE else View.GONE
添加一级页面和二级页面的跳转动画
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_container) as? NavHostFragment
val builder = NavOptions.Builder()
builder.setEnterAnim(R.anim.slide_in_from_right)
.setExitAnim(R.anim.slide_out_to_left)
.setPopEnterAnim(R.anim.slide_in_from_left)
.setPopExitAnim(R.anim.slide_out_to_right)
navHostFragment?.navController?.navigate(R.id.LoginScreen,null,builder.build())
二级页面返回
findNavController().navigateUp()