前言
在上一篇中对应Jetpack对应的Navigation进行了初步讲解。在本篇中,将会讲解对应的NavigationUI 以及DeepLink 相关内容!
1、NavigationUI
1.1 NavigationUI的作用
- Fragment的切换,除了Fragment页面本身的切换,通常还伴有App bar的变化。
- 为了方便管理,Navigation组件引入了
NavigationUI 类
1.2 示例一
对应navigation
如图所示
这里有两个Fragment,没有任何操作,对应Framgnet也只是一个TextView(就不贴对应xml布局代码了)。
对应meun
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/mainFragment"
android:icon="@drawable/ic_launcher_background"
android:title="主界面"/>
<item
android:id="@+id/settingsFragment"
android:icon="@drawable/ic_launcher_background"
android:title="设置界面"/>
</menu>
这里就两个选项,对应id需要和navigation 里面fragment相互对应。
来看看如何使用
class MainActivity : AppCompatActivity() {
private var navController: NavController? = null
private var appBarConfiguration: AppBarConfiguration? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
navController = Navigation.findNavController(this, R.id.fragmentContainerView)
appBarConfiguration = AppBarConfiguration.Builder(navController!!.graph).build()
NavigationUI.setupActionBarWithNavController(
this,
navController!!, appBarConfiguration!!
)
navController?.addOnDestinationChangedListener { controller, destination, arguments ->
Log.d("hqk", "onDestinationChanged")
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.menu_settings, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return NavigationUI.onNavDestinationSelected(
item,
navController!!
) || super.onOptionsItemSelected(item)
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(
navController!!,
appBarConfiguration!!
) || super.onSupportNavigateUp()
}
}
狠简单,一切尽在注释中,就这样,一个标准的action bar已经成型了!
来看看运行效果
有细心的小伙伴应该看到,在第二个Fragment时,对应菜单消失了。这里只是在第二个Fragment添加了一小部分代码:
SettingsFragment
class SettingsFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
setHasOptionsMenu(true)
return inflater.inflate(R.layout.fragment_settings, container, false)
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
menu.clear()
super.onCreateOptionsMenu(menu, inflater)
}
}
比较简单这个,来看看示例二
1.3 示例二
在示例一的基础上,创建新的BottomActivity
先看对应布局
如图所示
就在原有基础上添加了BottomNavigationView 控件,指定了对应app:menu="@menu/menu_settings"
再来看看如何使用
class BottomActivity : AppCompatActivity() {
private var navController: NavController? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_bottom)
navController = Navigation.findNavController(this, R.id.fragmentContainerView)
navController?.addOnDestinationChangedListener { controller, destination, arguments ->
Log.d("hqk", "onDestinationChanged")
}
NavigationUI.setupWithNavController(
findViewById<BottomNavigationView>(R.id.bottomNavigationView),
navController!!
);
}
}
就这样就好了,来看看运行效果!
1.4 更多支持
- App Bar
- ActionBar
- Toolbar
- CollapsingToolbarLayout
- menu
- 抽屉菜单(DrawLayout+Navigation View)
- 底部菜单(BottomNavigationView)
这里就不一一举例了,都非常简单。
2、DeepLink
- PendingIntent方式
- 当App收到某个通知推送,我们希望用户在点击该通知时,能够直接跳转到展示该通知内容的页面,可以通过PendingIntent来完成
- URL方式
- 当用户通过手机浏览器浏览网站上的某个页面时,可以在网页上放置一个类似于“在应用内打开”的按钮,如果用户手机安装由我们的App,那么通过DeepLink就能打开相应的页面;如果没有安装,那么网站可以导航到应用程序的下载页面,引导用户安装应用。
- 如果没有对应的网页可使用命令:
adb shell am start -a android.intent.action.VIEW -d "http://www.xxx.com/fromWeb" ,来模拟测试
2.1 PendingIntent方式
这里准备用上一篇的例子,在所有保持布局不动的情况下;
对应HomeFragment
class HomeFragment : Fragment() {
private var notificationId = 0
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_home, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val button: Button? = view?.findViewById(R.id.button)
button?.setOnClickListener {
sendNotification()
}
}
private fun sendNotification() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
requireActivity().packageName,
"MyChannel",
NotificationManager.IMPORTANCE_DEFAULT
)
channel.description = "My NotificationChannel"
val notificationManager = requireActivity().getSystemService(
NotificationManager::class.java
)
notificationManager.createNotificationChannel(channel)
}
val notification = NotificationCompat.Builder(
requireActivity(), requireActivity().packageName
)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Deep Link")
.setContentText("点击我试试...")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(getPendingIntent())
.build()
val notificationManagerCompat = NotificationManagerCompat.from(
requireActivity()
)
notificationManagerCompat.notify(notificationId++, notification)
}
private fun getPendingIntent(): PendingIntent {
val args = Bundle()
args.putString("name", "hqk")
return Navigation.findNavController(requireActivity(), R.id.button)
.createDeepLink()
.setGraph(R.navigation.my_nav_graph)
.setDestination(R.id.detailFragment)
.setArguments(args)
.createPendingIntent()
}
}
方法sendNotification 就是非常标准的通知栏代码,唯一不同的是获取PendingIntent 是通过Navigation.findNavController 获取!
来看看运行效果
OK,很简单的!直接下一个!
2.2 URL方式
这种方式更简单,
首先在对应navigation对应xml里添加
<?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/my_nav_graph"
app:startDestination="@id/homeFragment">
...略
<fragment
android:id="@+id/detailFragment"
android:name="com.hqk.navigation3.DetailFragment"
android:label="fragment_detail"
tools:layout="@layout/fragment_detail" >
<action
android:id="@+id/action_detailFragment_to_homeFragment"
app:destination="@id/homeFragment" />
添加如下代码
<deepLink app:uri="www.hqk.com/{params}"/>
</fragment>
</navigation>
其次在启动activity里添加如下代码
...略
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<nav-graph android:value="@navigation/my_nav_graph"/>
</activity>
...略
注意这里对应app:uri 是www.hqk.com/{params} 网址,用adb模拟运行试试:
当使用adb运行对应命令时,运行效果:
都是比较简单的内容
结束语
好了,本篇到这里就结束了!下一篇将开始对WorkManager的讲解!
|