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方式
- 在导航图中为页面添加标签。在app:uri属性中填入的是你的网站的相应Web页面地址,后面的参数会通过Bundle对象传递到页面中。
- 为Activity设置标签。当用户在Web页面中访问你的网站时,应用程序便能得到监听。
- 我们可以在Google app中输入相应的Web地址,也可以通过adb工具,使用命令行来完成操作。
更详细使用可参考:链接
以上是关于Android jetpack之Navigation的主要内容,如果未能解决你的问题,请参考以下文章
Android Jetpack架构组件之WorkManager