美文网首页
使用NavigationUI解决BottomNavigation

使用NavigationUI解决BottomNavigation

作者: 全汪汪 | 来源:发表于2019-04-23 16:30 被阅读0次

NavigationUI的作用

使用过Jetpack里的Navigation跳转的都知道,一个页面会有一个action指向另一个页面,代表页面A跳转到页面B,最后我们在代码里使用跳转就可以了:

Navigation.findNavController(this, 容器id).navigate(跳转的Id)

那么问题来了!如果我们要用BottomNavigationView来进行跳转该如何是好啊?

BottomNavigationView
如果我们按照传统的方法来,我们要自己弄一个BottomNavigationView的监听,然后判断点了哪个item再用哪个页面的id进行跳转。这种判断是繁琐的...
因此NavigationUI的存在就是方便我做联动的跳转,减少我们不必要的业务逻辑。
官网地址:https://developer.android.google.cn/guide/navigation/navigation-ui

NavigationUI的使用

根据官网文档,你会发现使用起来何其简单,只用一段代码:

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val navController = findNavController(R.id.nav_host_fragment)
    //调用NavigationUI的setupWithNavController方法
    val navController = Navigation.findNavController(this, R.id.fragment_container)
        NavigationUI.setupWithNavController(nv_bottom, navController)
}

然后当你运行的时候,你会发现:

完全没有用啊!!!!!!!!

这是为什么!然后我又仔细翻了下文档。又没有说明,只说了这个联动的大致原理:

NavigationUI uses OnDestinationChangedListener to make these common UI components navigation-aware.

NavigationUI 利用 NavController的OnDestinationChangedListener方法来达到联动的效果,这个接口是每当目的地或者其参数发生变化时就会被调用...
为什么没有用,那我们还是看下源码:

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的监听,然后我们点进去:

 public static boolean onNavDestinationSelected(@NonNull MenuItem item,
            @NonNull NavController navController) {
        NavOptions.Builder builder = new NavOptions.Builder()
                .setLaunchSingleTop(true)
                .setEnterAnim(R.anim.nav_default_enter_anim)
                .setExitAnim(R.anim.nav_default_exit_anim)
                .setPopEnterAnim(R.anim.nav_default_pop_enter_anim)
                .setPopExitAnim(R.anim.nav_default_pop_exit_anim);
        if ((item.getOrder() & Menu.CATEGORY_SECONDARY) == 0) {
            builder.setPopUpTo(findStartDestination(navController.getGraph()).getId(), false);
        }
        NavOptions options = builder.build();
        try {
            //TODO provide proper API instead of using Exceptions as Control-Flow.
            //用menu中item的id来作为跳转的目的地id
            navController.navigate(item.getItemId(), null, options);
            return true;
        } catch (IllegalArgumentException e) {
            return false;
        }
    }

你会惊喜地发现这里把我们点击的menu中item的id作为目的地id,而之前我们目的地的id一般是在我们自定义的nav_graph.xml这里定义的。也就是说如果你menu中item的id和nav_graph.xml自定义的fragment的id不一致的话是无法跳转的。因为id不对应。

<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/navigation_home">

    <fragment
        android:id="@+id/navigation_home"
        android:name="com.bondsteppay.mytest.Mainragment"
        tools:layout="@layout/fragment_mainf"/>

    <fragment
        android:id="@+id/navigation_dashboard"
        android:name="com.bondsteppay.mytest.SecondFragment"
        tools:layout="@layout/fragment_second"/>

    <fragment
        android:id="@+id/navigation_notifications"
        android:name="com.bondsteppay.mytest.fragment_third"
        android:label="fragment_fragment_third"
        tools:layout="@layout/fragment_third"/>

</navigation>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/title_home"/>

    <item
        android:id="@+id/navigation_dashboard"
        android:icon="@drawable/ic_dashboard_black_24dp"
        android:title="@string/title_dashboard"/>

    <item
        android:id="@+id/navigation_notifications"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:title="@string/title_notifications"/>

</menu>

如上述对应。id一致即可。

相关文章

网友评论

      本文标题:使用NavigationUI解决BottomNavigation

      本文链接:https://www.haomeiwen.com/subject/jpnvgqtx.html