写点什么

Jetpack 系列 (一) — Navigation

用户头像
Android架构
关注
发布于: 5 小时前

exit = R.anim.slide_out_leftpopEnter = R.anim.slide_in_leftpopExit = R.anim.slide_out_right}}


val flowStepNumber = 1val product = Product("可乐")val directions = HomeFragmentDirections.nextAction(flowStepNumber, product)findNavController().navigate(directions, options)

菜单跳转

NavigationUI 具有将菜单项与导航目的地相关联的静态方法,navigation-ui-ktx 是执行关联操作的一组扩展函数。如果 NavigationUI 在当前导航图上找到与目的地具有相同 ID 的菜单项,就会将该菜单项配置为导航到该目的地。


步骤一: 创建 menu 文件 overflow_menu.xml


<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/settings_dest"android:icon="@drawable/ic_settings"android:menuCategory="secondary"android:title="@string/settings" /></menu>


步骤二: 添加 menu 到菜单,添加选中事件


// 添加 menu 到菜单 override fun onCreateOptionsMenu(menu: Menu?): Boolean {menuInflater.inflate(R.menu.overflow_menu, menu)return true}


// menu 选中 override fun onOptionsItemSelected(item: MenuItem): Boolean {return item.onNavDestinationSelected(findNavController(R.id.my_nav_host_fragment))|| super.onOptionsItemSelected(item)}


步骤三: 修改 Graph 文件,注意 id 和 menu 文件保持一致,这里我特意把目的地设为 activity,因为我最先误解只能是 fragment


<activityandroid:id="@+id/settings_dest"android:name="com.hxdi.myapplication.SettingActivity"android:label="activity_seting"tools:layout="@layout/activity_seting" />

底部 Bottom

步骤一: 添加 BottomNavigationView


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


步骤二: 编写 menu, bottom_nav_menu.xml


<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@id/home_dest"android:icon="@drawable/ic_home"android:title="@string/home" /><itemandroid:id="@id/deeplink_dest"android:icon="@drawable/ic_android"android:title="@string/deeplink" /></menu>


步骤三: 关联 NavController


// 底部 Bottomprivate fun setupBottomNavMenu(navController: NavController) {binding.bottomNavView.setupWithNavController(navController)}


步骤四: 设置顶级界面,


appBarConfiguration = AppBarConfiguration(setOf(R.id.home_dest, R.id.deeplink_dest) // 顶级目的地)setupActionBar(navController, appBarConfiguration)

侧边 DrawLayout

步骤一:添加 NavigationView


<androidx.drawerlayout.widget.DrawerLayoutxmlns: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">


...


<com.google.android.material.navigation.NavigationViewandroid:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="start"app:menu="@menu/nav_drawer_menu"/></androidx.drawerlayout.widget.DrawerLayout>


步骤二: 编写 menu,nav_drawer_menu.xml,同上, 略


步骤二: 关联 NavController


appBarConfiguration = AppBarConfiguration(setOf(R.id.home_dest, R.id.deeplink_dest), // 顶级目的地 binding.drawerLayout // DrawerLayout)

桌面小插件

这一小节的功能是通过桌面插件跳转至 App 某个页面


步骤一: 通过 AppWidgetProvider 创建桌面插件,AppWidgetProvider 实质是 BroadcastReceiver


class DeepLinkAppWidgetProvider : AppWidgetProvider() {


override fun onUpdate(context: Context,appWidgetManager: AppWidgetManager,appWidgetIds: IntArray) {val remoteViews = RemoteViews(context.packageName,R.layout.deep_link_appwidget)val args = Bundle()args.putString("myarg", "From 桌面")val pendingIntent = NavDeepLinkBuilder(context).setGraph(R.navigation.mobile_navigation).setDestination(R.id.deeplink_dest) // 跳转目的地.setArguments(args) // 参数.createPendingIntent()remoteViews.setOnClickPendingIntent(R.id.deep_link_button, pendingIntent)


appWidgetManager.updateAppWidget(appWidgetIds, remoteViews)}}


步骤二: AppWidgetProvider 实质是 BroadcastReceiver,在配置文件当中注册


<receiver android:name=".DeepLinkAppWidgetProvider"><intent-filter><action android:name="android.appwidget.action.APPWIDG


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ET_UPDATE" /></intent-filter>


<meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/deep_link_appwidget_info" /></receiver>


步骤三: 为了观察效果,接受方也要处理一下


val myArg = arguments?.getString("myarg")binding.text.text = myArg

网页链接跳转

NavController 支持将网址直接映射到导航图中的目的地。


步骤一: 在目的地添加


<fragmentandroid:id="@+id/deeplink_dest"android:name="com.hxdi.myapplication.DeepLinkFragment"android:label="@string/deeplink"tools:layout="@layout/fragment_deep_link">


<argumentandroid:name="myarg"android:defaultValue="Android!"/>


<deepLink app:uri="www.example.com/{myarg}" />


</fragment>


步骤二: 修改配置文件, 添加 nav-graph


<activityandroid:name=".MainActivity"android:launchMode="singleTask"><intent-filter><action android:name="android.intent.action.MAIN" />


<category android:name="android.intent.category.LAUNCHER" /></intent-filter><nav-graph android:value="@navigation/mobile_navigation" /></activity>

通知栏跳转

本来以为到这里就结束了,但是发现例子当中还有一个通知跳转,索性也写一下,顺便复习一下通知的写法: 创建通知,NotificationManager =》 检测版本 =》 Andorid 8 以上 创建通道 =》notify


binding.button.setOnClickListener {val etArg = binding.etArg.text.toString()val args = Bundle()args.putString("myarg", etArg)


val deepLink = findNavController().createDeepLink().setDestination(R.id.deeplink_dest).setArguments(args).createPendingIntent()


val notificationManager =context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagerif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {notificationManager.createNotificationChannel(NotificationChannel("deepLink","消息",NotificationManager.IMPORTANCE_HIGH))}


val notification = NotificationCompat.Builder(requireContext(), "deepLink").setContentTitle("Navigation").setContentText("Deep link to Android").setSmallIcon(R.drawable.ic_android).setContentIntent(deepLink).setAutoCancel(true).build()


notificationManager.notify(0, notification)}

相关知识点

知识点一: actionBar 绑定


  • 要想 lable 显示 Graph 文件当中配置的文字,以及 actionBar 和 NavController 关联起来,需要如下步骤


// 步骤一 显示 ActionBarsetSupportActionBar(binding.toolbar)


// 步骤二 找到 NavHostFragmentval host: NavHostFragment = supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragmentval navController = host.navController


// 步骤三 关联 NavController 和 AppBarConfigurationappBarConfiguration = AppBarConfiguration(navController.graph) setupActionBarWithNavController(navController, appBarConfiguration)


知识点二: 点击事件


  • 语法层面上方式二和方式一三相同,但是 actionId 只使用于方式二,这个createNavigateOnClickListener() 内部创建 View 点击事件有关


// 跳转方式二 actionIdbinding.button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.next_action))binding.button.setOnClickListener {// 跳转方式一 idfindNavController().navigate(R.id.flow_step_fragment, null)// 跳转方式三 actionval directions = HomeFragmentDirections.nextAction()findNavController().navigate(directions)}


知识点三:路由监听


  • NavController 提供了全局的监听接口


// NavController 提供了全局的监听接口 navController.addOnDestinationChangedListener { controller, destination, arguments ->val dest: String = try {resources.getResourceName(destination.id)} catch (e: Resources.NotFoundException) {destination.id.toString()}Log.d("NavigationActivity", "Navigated to $dest")}

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Jetpack系列(一) — Navigation