Android jetpack之Navigation

Posted gujunhe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android jetpack之Navigation相关的知识,希望对你有一定的参考价值。

1.使用Navigation

1.1创建Navigation Graph

  • 在res文件夹下创建一个android Resource File,新建一个Navigation Graph文件,将File
    name设置为“nav_graph”,Resource type设置为“Navigation”。如下图所示:


点击确认后一定要选择自动帮你添加依赖,否则使用不了

1.2.添加NavHostFragment

  • NavHostFragment是一个特殊的Fragment,我们需要将其添加到Activity的布局文件中,作为其他Fragment的容器。
    这里我们直接修改mainactivity中的布局文件,添加:
 <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"//告诉系统这是一个特殊的Fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"//该Fragment会自动处理系统返回键。即当用户按下手机的返回按钮时,系统能自动将当前所展示的Fragment退出
        app:navGraph="@navigation/nav_graph"//用于设置该Fragment对应的导航图
/>

1.3.创建destination

  • 我们回到第一步创建的导航图上,点击加号按钮,创建一个destination,它可以是Fragment或Activity,但最常见的是Fragment,因为Navigation组件的作用是方便开发者在一个Activity中管理多个Fragment。在此,我们通过destination创建一个名为MainFragment的Fragment

  • 创建完mainFragment后,在navigation标签下有一个startDestination属性,该属性指定起始destination为mainFragment。

1.4.完成Fragment页面切换

  • 先创建一个SecondFragment,单击mainFragment,用鼠标选中其右侧的圆圈,并拖拽至右边的secondFragment,松开鼠标,此时出现一个从mainFragment指向secondFragment的箭头:

  • 可以看到多了一个标签,app:destination属性表示它的目的地是secondFragment:

1.5.使用NavControIIer完成导航

  • 经过以上步骤后,我们还需要通过NavController对象,在代码中完成具体的页面跳转工作。在MainFragment的布局文件中添加一个Button,接着打开MainFragment,响应这个按钮的单击事件,完成具体的页面切换。

1.6. 添加页面切换动画效果

  • 打开导航文件, 选中箭头,并在右边的Animations面板中为其设置动画文件,如图所示:

  • 事实上我们也可以在布局文件直接编写,Design面板只是使用了可视化的方式以方便操作。

2.使用safe args插件传递参数(略)

3.NavigationUI

3.1NavigationUI的意义

  • 导航图是Navigation组件中很重要的一部分,它可以帮助我们快速了解页面之间的关系,再通过NavController便可以完成页面的切换工作。而在页面的切换过程中,通常还伴随着Appbar中menu菜单的变化。对于不同的页面,App bar中的menu菜单很可能是不一样的。Appbar中的各种按钮和菜单,同样承担着页面切换的工作。例如,当ActionBar左边的返回按钮被单击时,我们需要响应该事件,返回到上一个页面。既然Navigation和Appbar都需要处理页面切换事件,那么,为了方便管理,Jetpack引入了NavigationUI组件,使Appbar中的按钮和菜单能够与导航图中的页面关联起来。

3.2NavigationUI使用

  • 假设我们有两个页面:MainFragment和SettingsFragment。这两个Fragment同属于MainActivity。我们希望MainFragment的ActionBar右边有一个按钮,通过该按钮,可以跳转到SettingsFragment。而在SettingsFragment的ActionBar左侧有一个返回按钮,通过该按钮,可以返回MainFragment。

  • 在menu_settings.xml文件中,为ActionBar添加菜单。注意,的id与导航图中SettingsFragment的id是一致的,这表示,当该被单击时,将会跳转到id所对应的Fragment,即SettingsFragment
  • menu代码 (id为要跳转的Fragment)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:id="@+id/settingsFragment"
    android:icon="@drawable/ic_launcher_foreground"
    android:title="设置界面"
    />
</menu>
  • 在MainActivity中实例化菜单:
 @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        getMenuInflater().inflate(R.menu.menu_settings,menu);
        return true;
    
  • NavigationUI组件响应菜单单击事件:
	private AppBarConfiguration appBarConfiguration;
    private NavController navController;
	navController= Navigation.findNavController(this,R.id.nav_host_fragment);
	AppBarConfiguration configuration = new AppBarConfiguration.Builder(controller.getGraph()).build();
	NavigationUI.setupActionBarWithNavController(this,navController,appBarConfiguration);
 @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) 
        return NavigationUI.onNavDestinationSelected(item,navController)||super.onOptionsItemSelected(item);
    

    @Override
    public boolean onSupportNavigateUp() 
        return NavigationUI.navigateUp(navController,appBarConfiguration)||super.onSupportNavigateUp();
    
  • 由于在导航图和菜单的布局文件中,我们已经为SettingsFragment设置好了相同的id(即settingsFragment)。因此,在onOptionsItemSelected()方法中,通过NavigationUI便可以自动完成页面跳转。
  • 希望在页面切换时能够收到通知,做一些自定义操作该怎么办呢?Jetpack也考虑到了这一点。我们可以利用NavController提供的一个名为OnDestinationChangedListener的接口,对页面切换事件进行监听:
navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() 
            @Override
            public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) 
                //收到切换事件
            
        );

3.3NavigationUI实现导航栏

  • 先创建导航栏的menu菜单,接着添加BottomNavigationView组件,同样要注意的是,menu中每个Item的id一定要和每个Fragment的id一致,否则导航无法生效。

menud代码:

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

    <item android:title="111"
        android:id="@+id/mainFragment"
        android:icon="@drawable/ic_buttom_home_24"/>
    <item android:title="222"
        android:id="@+id/secondFragment"
        android:icon="@drawable/ic_buttom_shopping_cart_24"/>
    <item android:title="333"
        android:id="@+id/settingsFragment"
        android:icon="@drawable/ic_buttom_mine_24"/>
</menu>

设置导航:

    NavController navController= Navigation.findNavController(this,R.id.nav_host_fragment);
    AppBarConfiguration configuration = new AppBarConfiguration.Builder(bottomNavigationView.getMenu()).build();
	NavigationUI.setupActionBarWithNavController(this,navController,configuration);
    NavigationUI.setupWithNavController(bottomNavigationView,navController);

4.深层链接DeepLink

Navigation组件还有一个非常重要和实用的特性DeepLink,即深层链接。通过该特性,我们可以利用PendingIntent或一个真实的URL链接,直接跳转到应用程序中的某个页面(Activity/Fragment)。常见的两种应用场景如下。

  • PendingIntent的方式。当应用程序接收到某个通知推送,你希望用户在单击该通知时,能够直接跳转到展示该通知内容的页面,那么可以通过PendingIntent来完成此操作。
  • URL的方式。当用户通过手机浏览器浏览网站上的某个页面时,可以在网页上放置一个类似于“在应用内打开”的按钮。如果用户的手机安装有我们的应用程序,那么通过DeepLink就能打开相应的页面;如果没有安装,那么网站可以导航到应用程序的下载页面,从而引导用户安装应用程序。

4.1.PendingIntent方式

4.2.URL方式

  1. 在导航图中为页面添加标签。在app:uri属性中填入的是你的网站的相应Web页面地址,后面的参数会通过Bundle对象传递到页面中。
  2. 为Activity设置标签。当用户在Web页面中访问你的网站时,应用程序便能得到监听。
  3. 我们可以在Google app中输入相应的Web地址,也可以通过adb工具,使用命令行来完成操作。

更详细使用可参考:链接

以上是关于Android jetpack之Navigation的主要内容,如果未能解决你的问题,请参考以下文章

Android Jetpack之ViewModel源码分析

Android Jetpack之LiveData源码分析

Android---Jetpack之LiveData

Android Jetpack架构组件之WorkManager

Android Jetpack之Navigation源码分析

jetpack之databinding