Jetpack架构组件学习(3)——Activity Results API使用
原文地址:Jetpack架构组件学习(3)——Activity Results API使用 - Stars-One的杂货小窝
技术与时俱进,页面跳转传值一直使用的是startActivityForResult
方法,如今有了新的API实现方式,学习并稍微总结下
startActivityForResult复习
MainActivity代码:
Main2Activity代码:
效果:
上面的代码应该是比较基础的代码,这里我就不再赘述了
主要说些缺点
所有逻辑都在onActivityResult()
方法里进行判断,根据requestCode
和resultCode
进行判断
如果单个还好说,但是如果有多个的,就会看见onActivityResult()
里一堆的if逻辑,阅读起来就十分繁琐,且维护困难
谷歌官方也是考虑到了这个,于是便是在新版本推出了个Activity Results API去替代了上面所述的方式,下面就介绍下如何使用
简单使用
1.引入依赖
首先,需要我们引入依赖:
implementation 'androidx.appcompat:appcompat:1.3.1'
PS: 请使用1.3.1以上版本,低版本没有这个枚举类
ActivityResultContracts
我们先以上面的例子,使用Activity Results API
Main2Acitivity
代码不用动,我们只需要调整MainActivity
文件里代码,如下所示:
2.创建契约
val contract = ActivityResultContracts.StartActivityForResult()
contract变量的对象类名为ActivityResultContract
ActivityResultContracts
相当于一个枚举类,是谷歌官方贴心封装的,里面提供了一些常用的ActivityResultContract
类对象供我们使用
像拍照,申请权限的等操作,从代码提示就可以看到了,如下图所示:
这里我们选用StartActivityForResult()
,字面意思应该很好理解,就是应用在就是页面跳转并返回数据的情景
PS:根据我们选用的ActivityResultContracts,会影响第4步中的传参类型
下面补充下对应的选择说明:
StartActivityForResult
: 通用的Contract,不做任何转换,Intent作为输入,ActivityResult作为输出,这也是最常用的一个协定。CreateDocument
: 提示用户选择一个文档,返回一个(file:/http:/content:)开头的Uri。GetContent
: 提示用选择一条内容,返回一个通过ContentResolver#openInputStream(Uri)访问原生数据的Uri地址(content://形式) 。默认情况下,它增加了 Intent#CATEGORY_OPENABLE, 返回可以表示流的内容。GetMultipleContents
:获取多条内容OpenDocument
: 提示用户选择指定类型文件(输入参数为mimeType),返回用户所选文件UriOpenDocumentTree
: 提示用户选择一个目录,并返回用户选择的作为一个Uri返回,应用程序可以完全管理返回目录中的文档。OpenMultipleDocuments
: 提示用户选择文档(可以选择多个),分别返回它们的Uri,以List的形式。PickContact
: 从通讯录APP获取联系人RequestMultiplePermissions
:用于请求一组权限RequestPermission
: 用于请求单个权限TakePicturePreview
: 调用MediaStore.ACTION_IMAGE_CAPTURE
拍照,返回值为Bitmap图片TakePicture
: 调用MediaStore.ACTION_IMAGE_CAPTURE
拍照,并将图片保存到给定的Uri地址,返回true表示保存成功。TakeVideo
: 调用MediaStore.ACTION_VIDEO_CAPTURE
拍摄视频,保存到给定的Uri地址,返回一张缩略图。
具体参数和说明可以使用的时候查看文档哦~
实际上,如果上面所列还不能满足我们的需求,那么我们也可以自定义契约操作,在文章下面再进行补充说明,这里就先不进行扩展了
3.建立契约(注册Contact)
//注册ActivityResultContract
val myLauncher = registerForActivityResult(contract){
if (it.resultCode==2) {
val data = it.data
if (data != null) {
val resultData = data.getStringExtra("mydata")
Toast.makeText(this, resultData, Toast.LENGTH_SHORT).show()
}
}
}
使用Activity类中registerForActivityResult()
方法,进行契约的注册,实际上就是相当于注册了一个监听,之后从Main2Activity页面返回MainActivity页面,会回调这个里面的方法
注意: 这里有个变量myLauncher,之后第三步需要使用
4.发起页面跳转
val intent = Intent(this, Main2Activity::class.java)
myLauncher.launch(intent)
调用myLauncher对象的launch()
方法,将intent对象传递即可实现页面跳转的操作
PS: 这里还是在按钮的点击事件里,方便阅读就省略了
之后从Main2Activity页面返回之后,会回调第二步中的操作,效果与上面的动图演示一致,这里就不再重新贴个图了
自定义ActivityResultContract
ActivityResultContract
实际上还包含两个泛型,完整应该是这样ActivityResultContract<I,O>
I
为input的意思,意为输入参数类型O
为output的意思,意为输出参数类型
ActivityResultContract<I,O>
是个抽象类,我们想要实现自定义,那么就直接继承它
class MyContract: ActivityResultContract<String, String>() {
override fun createIntent(context: Context, input: String?): Intent {
//这里input的类型,就是上文说到的I
}
override fun parseResult(resultCode: Int, intent: Intent?): String {
//这里方法返回的结果类型,就是上文说到的O
}
}
继承发现,需要我们实现两个方法,createIntent()
和parseResult()
一眼过去其实很好理解,createIntent()
就是创建一个intent对象,调用launch()
方法的时候(上面使用的第4步操作),里面就会根据此intent进行页面的跳转操作
而parseResult()
方法,则是建立契约那步,里面回调的数据类型
我们以上面的例子,发现我们还得声明一个Intent对象传递,以及回传的时候还得通过intent对象去获取数据,有些繁琐,有些代码可以封装成通用的
照着这个想法,我们可以实现一个自定义ActivityResultContract,传递页面参数即可拿到Main2Activity返回的数据,代码如下所示:
class MyContract: ActivityResultContract<KClass<out Activity>, String>() {
override fun parseResult(resultCode: Int, intent: Intent?): String? {
if (resultCode == 2 && intent!=null) {
return intent.getStringExtra("mydata")
}
return null
}
override fun createIntent(context: Context, input: KClass<out Activity>?): Intent {
val intent = Intent(context,input?.java)
return intent
}
}
使用:
//1.创建契约
val contract = MyContract()
//2.注册ActivityResultContract
val myLauncher = registerForActivityResult(contract){
Toast.makeText(this, it, Toast.LENGTH_SHORT).show()
}
btnGo.setOnClickListener {
//2.发起页面跳转
myLauncher.launch(Main2Activity::class)
}
当然,这里还可以优化,如我们让MyContract多个构造函数,这样取值的key也可以通过此进行定义
class MyContract(val key: String) : ActivityResultContract<KClass<out Activity>, String>() {
override fun parseResult(resultCode: Int, intent: Intent?): String? {
if (resultCode == 2 && intent != null) {
return intent.getStringExtra(key)
}
return null
}
override fun createIntent(context: Context, input: KClass<out Activity>?): Intent {
val intent = Intent(context, input?.java)
return intent
}
}
使用:
//创建契约里传参即可
val contract = MyContract("mydata")
参考
Jetpack架构组件学习(3)——Activity Results API使用的更多相关文章
- Jetpack架构组件学习(1)——LifeCycle的使用
原文地址:Jetpack架构组件学习(1)--LifeCycle的使用 | Stars-One的杂货小窝 要看本系列其他文章,可访问此链接Jetpack架构学习 | Stars-One的杂货小窝 最近 ...
- Jetpack架构组件学习(2)——ViewModel和Livedata使用
要看本系列其他文章,可访问此链接Jetpack架构学习 | Stars-One的杂货小窝 原文地址:Jetpack架构组件学习(2)--ViewModel和Livedata使用 | Stars-One ...
- Jetpack架构组件学习(4)——APP Startup库的使用
最近在研究APP的启动优化,也是发现了Jetpack中的App Startup库,可以进行SDK的初始化操作,于是便是学习了,特此记录 原文:Jetpack架构组件学习(4)--App Startup ...
- Jetpack 架构组件 Room 数据库 ORM MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Jetpack 架构组件 LiveData ViewModel MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Jetpack 架构组件 Lifecycle 生命周期 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Android 架构:Android Jetpack 架构组件的学习和分析
参考:https://mp.weixin.qq.com/s/n-AzV7Ke8wxVhmC6ruUIUA 参考:https://jekton.github.io/2018/06/30/android- ...
- Android Jetpack 架构组件最佳实践之“网抑云”APP
背景 近几年,Android 相关的新技术层出不穷.往往这个技术还没学完,下一个新技术又出来了.很多人都是一脸黑人问号? 不少开发者甚至开始哀嚎:"求求你们别再创造新技术了,我们学不动了!& ...
- Android 四大组件学习之Activity六
本节学习Activity的状态保存与恢复. 先用样例開始: 布局文件主要是实现例如以下.大家自行编写 Activity逻辑代码: public class FiveActivity extends A ...
随机推荐
- linux 后台运行
一般用 nohup program & 运行状态用cat nohup.txt查询 下面这种关了终端也不会停止 setsid program &>xx.log & 若是不需 ...
- Uncaught TypeError: document.getElementsById is not a function
今天博主终于开始攻关javascript(俗称js)了,不过要注意了,它和java可是一丁点关系都没有,就像老婆饼和老婆一样. 下面就让我们来讨论一下博主这次犯下的低级错误吧 一.背景(解决方法在文末 ...
- pycharm——import已存在的库居然失败!
问题 明明在cmd中可以import的库,放到pycharm中却找不到. 问题根源 找了一圈,最后得到这个结论. 因为pycharm默认就是这样的... 解决 打开设置,找到解释器 点击右边齿轮图标, ...
- Java---变量和基本数据类型
变量 在Java中,变量分为两种:基本类型的变量和引用类型的变量. 在Java中变量必须先定义后使用,在定义变量的时候可以给它一个初始值.如果不写初始值,默认为0或空. 变量的一个重要特点是可以重新赋 ...
- 序列化和反序列化为什么要实现Serializable接口?(史上最全、简单易懂)
目录结 前言 1.什么是序列化和反序列化 2.什么时候需要进行序列化和反序列化 2.1.服务器和浏览器交互时用到了Serializable接口吗? 2.2.Mybatis将数据持久化到数据库中用到了S ...
- SSM实现个人博客-day04
项目源码免费下载:SSM实现个人博客 有问题询问vx:kht808 3.项目搭建(SSM整合) (1)创建maven工程,导入相应的依赖 <properties> <project. ...
- Java语言学习day27--8月02日
今日内容介绍1.Eclipse常用快捷键操作2.Eclipse文档注释导出帮助文档3.Eclipse项目的jar包导出与使用jar包4.不同修饰符混合使用细节5.辨析何时定义变量为成员变量6.类.抽象 ...
- 工作小记:企业微信 嵌H5页面 用户权限获取匹配
一.背景 领导让研究一个活儿:企业微信开发H5应用,微信端客户进入H5页面跟现有的Web系统打通用户权限.通俗的讲:嵌入企业微信H5页面,客户点进去按原权限加载内容.开发者中心有文档,附上两个关键链接 ...
- 2021.12.08 [SHOI2009]会场预约(平衡树游码表)
2021.12.08 [SHOI2009]会场预约(平衡树游码表) https://www.luogu.com.cn/problem/P2161 题意: 你需要维护一个 在数轴上的线段 的集合 \(S ...
- Sliding Window - 题解【单调队列】
题面: An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving fr ...