Navigation系列——进阶篇

作者

大家好,我叫小琪;

本人16年毕业于中南林业科技大学软件工程专业,毕业后在教育行业做安卓开发,后来于19年10月加入37手游安卓团队;

目前主要负责国内发行安卓相关开发,同时兼顾内部几款App开发。

目录

前言

上篇对Navigation的一些概念进行了介绍,并在前言中提到了app中常用的一个场景,就是app的首页,一般都会由一个activity+多个子tab组成,这种场景有很多种实现方式,比如可以使用RadioGroup、FrgmentTabHost、TabLayout或者自定义view等方式,但这些都离不开经典的FragmentManager来管理fragment之间的切换。

现在,我们有了新的实现方式,Navigation+BottomNavigationView,废话不多说,先看最终要实现的效果

第一个实例

先确保引入了navigation相关依赖

implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.1'

很简单,包含三个页面,首页、发现、我的,点击底部可以切换页面,有了上一篇的基础,先新建一个nav_graph的导航资源文件,包含三个framgent子节点

<?xml version="1.0" encoding="utf-8"?>
<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/nav_graph"
    app:startDestination="@id/FragmentHome">

    <fragment
        android:id="@+id/FragmentHome"
        android:name="com.example.testnavigation.FragmentHome"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home">
    </fragment>
    <fragment
        android:id="@+id/FragmentDicover"
        android:name="com.example.testnavigation.FragmentDicover"
        android:label="fragment_discover"
        tools:layout="@layout/fragment_discover">
    </fragment>
    <fragment
        android:id="@+id/FragmentMine"
        android:name="com.example.testnavigation.FragmentMine"
        android:label="fragment_mine"
        tools:layout="@layout/fragment_mine">
    </fragment>
</navigation>

然后在activity的布局中(这里为MainActivity的activity_main)中添加BottomNavigationView控件,

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />

</androidx.constraintlayout.widget.ConstraintLayout>

其中fragment节点在上面已经介绍过了,这篇不再讲解,BottomNavigationView是谷歌的一个实现底部导航的组件, app:menu属性为底部导航栏指定元素,新建一个bottom_nav_menu的menu资源文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/FragmentHome"
        android:icon="@mipmap/icon_tab_home"
        android:title="首页" />

    <item
        android:id="@+id/FragmentDicover"
        android:icon="@mipmap/icon_tab_find"
        android:title="发现" />

    <item
        android:id="@+id/FragmentMine"
        android:icon="@mipmap/icon_tab_mine"
        android:title="我的" />

</menu>

注意:这里item标签的id和上面nav_graph中fragment标签的id一致

资源准备好后,在MainActivity中

class MainActivity : AppCompatActivity() {
   
    override fun onCreate(savedInstanceState: Bundle?) {
   
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //fragment的容器视图,navHost的默认实现——NavHostFragment
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragment) as NavHostFragment

        //管理应用导航的对象
        val navController = navHostFragment.navController

        //fragment与BottomNavigationView的交互交给NavigationUI
        bottom_nav_view.setupWithNavController(navController)
    }
}

通过NavigationUI库,将BottomNavigationView和navigation关联,就能实现上面的效果图了,是不是so easy!

是不是很疑惑,这是怎么做到的?,此时我们进到源码看看,进入setupWithNavController方法

fun BottomNavigationView.setupWithNavController(navController: NavController) {
   
    NavigationUI.setupWithNavController(this, navController)
}

再进入

public static void setupWithNavController(
        @NonNull final BottomNavigationView bottomNavigationView,
        @NonNull final NavController navController) {
   
    bottomNavigationView.setOnNavigationItemSelectedListener(
            new BottomNavigationView.OnNavigationItemSelectedListener() {
   
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
   
                    return onNavDestinationSelected(item, navController);
                }
            });
   ......
}

在这里可以看到,给bottomNavigationView设置了一个item点击事件,进到onNavDestinationSelected方法,

public static boolean onNavDestinationSelected(@NonNull MenuItem item,
        @NonNull NavController navController) {
   
    NavOptions.Builder builder = new NavOptions.Builder()
            .setLaunchSingleTop(true)
            .setEnterAnim(R.animator.nav_default_enter_anim)
            .setExitAnim(R.animator.nav_default_exit_anim)
            .setPopEnterAnim(R.animator.nav_default_pop_enter_anim)
            .setPopExitAnim(R.animator.nav_default_pop_exit_anim);
    if 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值