Activity Results 总结和封装
封装后的API
很易用, 而且一看就知道是原理, 这还要总结啥, kotlin
lambda
yyds!
具体可以展开如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCaller
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
/**
* Author zsqw123
* Create by damyjy
* Date 2021/7/10 13:38
*/
fun ActivityResultCaller.takePhoto(targetUri: Uri, callback: (Boolean) -> Unit) =
registerForActivityResult(ActivityResultContracts.TakePicture(), callback).launch(targetUri)
fun ActivityResultCaller.takePhoto(callback: (Bitmap) -> Unit) =
registerForActivityResult(ActivityResultContracts.TakePicturePreview(), callback).launch(null)
fun ActivityResultCaller.requestPermissions(vararg permissions: String, callback: (Map<String, Boolean>) -> Unit) =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions(), callback).launch(permissions)
fun ActivityResultCaller.takeVideo(targetUri: Uri, callback: (Bitmap) -> Unit) =
registerForActivityResult(ActivityResultContracts.TakeVideo(), callback).launch(targetUri)
fun ActivityResultCaller.pickContact(callback: (Uri) -> Unit) =
registerForActivityResult(ActivityResultContracts.PickContact(), callback).launch(null)
fun ActivityResultCaller.getContent(mimeType: String, callback: (Uri) -> Unit) =
registerForActivityResult(ActivityResultContracts.GetContent(), callback).launch(mimeType)
fun ActivityResultCaller.createDocument(defaultName: String, callback: (Uri) -> Unit) =
registerForActivityResult(ActivityResultContracts.CreateDocument(), callback).launch(defaultName)
fun ActivityResultCaller.openDocuments(vararg mimeType: String, callback: (List<Uri>) -> Unit) =
registerForActivityResult(ActivityResultContracts.OpenMultipleDocuments(), callback).launch(mimeType)
fun ActivityResultCaller.openDocument(vararg mimeType: String, callback: (Uri) -> Unit) =
registerForActivityResult(ActivityResultContracts.OpenDocument(), callback).launch(mimeType)
fun ActivityResultCaller.openDocumentTree(defaultUri: Uri? = null, callback: (Uri) -> Unit) =
registerForActivityResult(ActivityResultContracts.OpenDocumentTree(), callback).launch(defaultUri)
inline fun <reified C> ComponentActivity.startAndResult(vararg pairs: Pair<String, Any>, noinline callback: (ActivityResult) -> Unit) =
registerForActivityResult(ActivityResultContracts.StartActivityForResult(), callback)
.launch(Intent(this, C::class.java).apply { putExtras(bundleOf(*pairs)) })
inline fun <reified C> Fragment.startAndResult(vararg pairs: Pair<String, Any>, noinline callback: (ActivityResult) -> Unit) =
registerForActivityResult(ActivityResultContracts.StartActivityForResult(), callback)
.launch(Intent(context, C::class.java).apply { putExtras(bundleOf(*pairs)) })
|
什么? 你不知道如何获取一个文件的mimeType
? 没关系, Java
有自带方法的, 这里我做了包装
1
2
3
4
|
object typeMap {
operator fun get(file: File): String = URLConnection.getFileNameMap().getContentTypeFor(file.name) ?: ""
operator fun get(fileName: String): String = get(File(fileName))
}
|
使用起来极为舒适:
1
|
val mimeType = typeMap[name]
|
哦?
你以为真的这么简单就你用了吗?没错,这种API
看起来简单直白,大多数人可能都会认为官方应该是这么用的,但实际上当你运行后会报错如下:
1
|
java.lang.IllegalStateException: LifecycleOwner com.zsqw123.learner.other.permission.storage.StorageAct@1c344622 is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.
|
实际上这玩意他要求在使用之前先把回调搞好, 然后再去获取并launch
!!!很气愤 但是就这样结束了吗? 我会屈服吗? 怎么可能! 直接将全部事件加入pending
中, 调用的时候修改map
中的函数类型调用即可
1
2
|
val ActivityResultCaller.pendingResults: SparseArray<(Any) -> Unit> by lazy { SparseArray() }
val ActivityResultCaller.pendingLaunches: SparseArray<ActivityResultLauncher<*>> by lazy { SparseArray() }
|
而相对应的我们在调用对应的触发事件的函数的同时, 从map
里面取出来进行一下launch
操作即可:
1
2
3
4
|
fun ActivityResultCaller.takePhoto(callback: (Bitmap) -> Unit) {
pendingResults[1] = { callback(it as Bitmap) }
pendingLaunches[1].launch(null)
}
|
完整代码: new-1-ActivityResults (github.com)