Android—Jetpack教程(八)

前言

在上一篇中对应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")
        }
    }

    //设置Action 菜单
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        super.onCreateOptionsMenu(menu)
        menuInflater.inflate(R.menu.menu_settings, menu)
        return true
    }

    //Action Bar菜单选项选中时
    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? {

        //这句代码和下面onCreateOptionsMenu相互对应,当为true时,将会调用onCreateOptionsMenu方法
        setHasOptionsMenu(true)
        return inflater.inflate(R.layout.fragment_settings, container, false)
    }


    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        //当加载这个Fragment时,对应菜单消失
        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:uriwww.hqk.com/{params}网址,用adb模拟运行试试:

当使用adb运行对应命令时,运行效果:

都是比较简单的内容

结束语

好了,本篇到这里就结束了!下一篇将开始对WorkManager的讲解!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值