从0到1打造一款安卓app之8-使用BottomNavigationView+Navigation实现主页

2,355 阅读1分钟

从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()