前言
最近产品小姐姐提出和苹果一样"3D Touch"类似的功能,刚好谷歌提供了"Shortcuts"相关快捷方式Api,本文就参照某地图软件快捷方式效果实现
参考效果
某地图快捷方式效果展示
提取功能点
-
长按显示快捷方式列表
-
显示广告页
-
跳转目标页面
-
目标页面返回首页
具体实现
创建快捷方式
官方提供了静态和动态创建两种方式,这里主要介绍动态创建,它更加灵活.
代码很简单,看注释即可
val shortcutItemList = mutableListOf<ShortcutInfoCompat>()
//用于演示只创建一个 "从这里出发" 的快捷方式
//1.构建任务栈列表
val intentList = arrayOf()
//2.创建快捷方式条目
val shortcutItem = ShortcutInfoCompat
//设置唯一Id
.Builder(context, "shortcut_id")
//条目显示的文本,设置成一样即可
.setShortLabel("从这里出发")
.setLongLabel("从这里出发")
//设置图标
.setIcon(IconCompat.createWithResource(context, R.mipmap.ic_launcher_round))
//设置任务栈
.setIntents(intentList)
.build()
shortcutItemList.add(shortcutItem)
//3.将自定义快捷方式列表导入管理器
ShortcutManagerCompat.setDynamicShortcuts(context, shortcutItemList)
设置Intent
这里的Intent 指的是点击快捷方式后,需要的跳转的界面,一般 setIntent() 即可,但是从前面的效果可以看出,跳转到目标界面后,此时我们点击返回需要返回到首页,这时候我们就可以使用setIntents()
官网说明
使用ShortcutInfoCompat.Builder创建快捷方式时,您可以使用 setIntents() 代替 setIntent()。通过调用 setIntents(),您可以在用户选择某个快捷方式时在应用内启动多个 Activity,同时将列表中除最后一个 Activity 之外的所有 Activity 放到返回堆栈上...
目标界面分析
我们需要实现的核心功能
- 长按快捷方式(广告页 -> 导航页 )
- 点击返回(导航页 -> 首页)
这里我将首页作为第一个界面,广告页作为"目标页面",当广告页启动后,立即跳转导航页,并finish广告页, 这时任务栈就只有首页和导航页,点击返回后,就返回到了首页了.也就达到了目标效果
完整intentList
//1.构建任务栈列表
val intentList = arrayOf(
//TODO 定义目前界面返回后显示的界面,一般是首页
Intent(context, MainActivity::class.java).apply {
action = Intent.ACTION_MAIN
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
},
//这里用SplashActivity充当处理Shortcuts逻辑的页面
Intent(context, SplashActivity::class.java).apply {
//TODO 目标快捷方式必须设置action,否者报错,任意action即可
action = Intent.ACTION_VIEW
//TODO 官网推荐,配合taskAffinity 使用
flags = Intent.FLAG_ACTIVITY_NEW_TASK
//TODO 这是意图参数
putExtra("action_id", "guide")
}
)
Manifest
<activity
android:name=".SplashActivity"
android:excludeFromRecents="true"
android:noHistory="true"
android:taskAffinity="">
</activity>
注意点
-
创建Intent 必须设置action,否者报错
-
目标界面最好配置 taskAffinity(官方推荐)
-
使用taskAffinity最好指定excludeFromRecents,noHistory,否者任务栈会有记录
官网
从一个 Activity 启动另一个 Activity
静态快捷方式不能有自定义 intent 标记。 静态快捷方式的第一个 intent 始终设置有 Intent.FLAG_ACTIVITY_NEW_TASK和Intent.FLAG_ACTIVITY_CLEAR_TASK。这意味着,如果应用已在运行,则在静态快捷方式启动时,应用中的所有现有 Activity 都会被销毁。如果不希望出现这种行为,您可以使用 Trampoline Activity,或者使用一个先在 Activity.onCreate(Bundle) 中启动其他 Activity、而后调用Activity.finish()的不可见 Activity:
- 在 AndroidManifest.xml 文件中,Trampoline Activity 应包含属性分配 android:taskAffinity=""。
- 在快捷方式资源文件中,静态快捷方式内的 intent 应引用 Trampoline Activity。
实现跳转逻辑
我们在构建Intent 时可以传入自定义参数,可用控制跳转逻辑,Demo这部分代码很简单,直接上代码
class SplashActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
//TODO 区分是默认启动还是普通启动
val action = intent.getStringExtra("action_id")
handlerAction(action)
}
fun handlerAction(action: String?) {
when (action) {
"guide" -> startToGuide()
else -> startToMain()
}
}
fun startToMain() {
thread {
sleep(2000)
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
}
fun startToGuide() {
thread {
sleep(500)
val intent = Intent(this, GuideActivity::class.java)
startActivity(intent)
finish()
}
}
}
效果展示
这里的三个界面都是某地图软件截图,关注跳转逻辑即可,通过Shortcuts我们可以很容易给App增加快捷方式的入口功能
虽然目前定制能力有限,但基本满足了开发需求,真是Biu倍爽
特别注意
-
快捷方式显示效果不一致,不同厂商的ROM实现不一样
-
定制能力有限,只能简单定制下图标
-
最好不要修改字体(亮/暗模式切换后,会自动修改文字颜色,手动修改后失效)
-
动态状态快捷方式,至少启动过一次App才能生效,后续启动不需要(第一次安装未启动时,长按)