背景
MAUI的呈现,赋予了宽广.Net开发者开发多平台利用的能力,MAUI 是Xamarin.Forms演变而来,然而相比Xamarin性能更好,可扩展性更强,构造更简略。然而MAUI对于平台相干的实现并不残缺。所以MASA团队发展了一个实验性我的项目,意在对微软MAUI的补充和扩大
我的项目地址https://github.com/BlazorComp...
每个性能都有独自的demo演示我的项目,思考到app安装文件体积(尽管MAUI曾经集成裁剪性能,然而该性能对于代码自身有影响),届时每一个性能都会以独自的nuget包的模式提供,不便测试,当初我的项目才刚刚开始,然而置信很快就会有能够交付的内容啦。
前言
本系列文章面向挪动开发小白,从零开始进行平台相干性能开发,演示如何参考平台的官网文档应用MAUI技术来开发相应性能。
介绍
Jetpack 蕴含一系列 Android 库,它们都采纳最佳做法并在 Android 利用中提供向后兼容性。
https://developer.android.goo...
上一篇咱们是通过Intent实现的,明天咱们用Jetpack 实现相册的多选性能。
一、实现形式
能够应用以下 activity 后果协定来启动照片选择器:
PickVisualMedia,用于抉择单张图片或单个视频。
PickMultipleVisualMedia,用于抉择多张图片或多个视频。
咱们的需要是能够多选照片,咱们次要介绍PickMultipleVisualMedia的应用办法。
咱们先看一下JAVA的示例代码
JAVA代码// Registering Photo Picker activity launcher with multiple selects (5 max in this example)ActivityResultLauncher<PickVisualMediaRequest> pickMultipleMedia = registerForActivityResult(new PickMultipleVisualMedia(5), uris -> { // Callback is invoked after the user selects media items or closes the // photo picker. if (!uris.isEmpty()) { Log.d("PhotoPicker", "Number of items selected: " + uris.size()); } else { Log.d("PhotoPicker", "No media selected"); }});// For this example, launch the photo picker and allow the user to choose images// and videos. If you want the user to select a specific type of media file,// use the overloaded versions of launch(), as shown in the section about how// to select a single media item.pickMultipleMedia.launch(new PickVisualMediaRequest.Builder() .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE) .build());
这里先介绍一下registerForActivityResult
在Android中启动另一个 activity(无论是您利用中的 activity 还是其余利用中的 activity)不肯定是单向操作。咱们须要获取activity的返回后果。这里咱们就是启动了相册,并获取用户选取照片的返回后果。其余例如关上相机获取拍照后果,关上通讯录获取联系人后果都是具体的利用场景。
尽管所有 API 级别的 Activity 类均提供底层 startActivityForResult() 和 onActivityResult() API,但Android官网强烈建议应用 AndroidX Activity 和 Fragment 中引入的 Activity Result API。
Activity Result API 提供了用于注册后果、启动后果以及在零碎分派后果后对其进行解决的组件。
在启动 activity 以获取后果时,可能会呈现您的过程和 activity 因内存不足而被销毁的状况;如果是应用相机等内存密集型操作,简直能够确定会呈现这种状况。
因而,Activity Result API 会将后果回调从您之前启动另一个 activity 的代码地位拆散开来。因为在从新创立过程和 activity 时须要应用后果回调,因而每次创立 activity 时都必须无条件注册回调,即便启动另一个 activity 的逻辑仅基于用户输出内容或其余业务逻辑也是如此。
位于 ComponentActivity 或 Fragment 中时,Activity Result API 会提供 registerForActivityResult() API,用于注册后果回调。registerForActivityResult() 承受 ActivityResultContract 和 ActivityResultCallback 作为参数,并返回 ActivityResultLauncher,用来启动另一个 activity。
ActivityResultContract 定义生成后果所需的输出类型以及后果的输入类型。这些 API 可为拍照和申请权限等根本 intent 操作提供默认协定。当然也能够创立本人的自定义协定。
ActivityResultCallback 是繁多办法接口,带有 onActivityResult() 办法,可承受 ActivityResultContract 中定义的输入类型的对象:
JAVA代码// GetContent creates an ActivityResultLauncher<String> to allow you to pass// in the mime type you'd like to allow the user to selectActivityResultLauncher<String> mGetContent = registerForActivityResult(new GetContent(), new ActivityResultCallback<Uri>() { @Override public void onActivityResult(Uri uri) { // Handle the returned Uri }});
这里的代码看起来很简略,咱们只须要在registerForActivityResult的第二个参数中new一个ActivityResultCallback并重写onActivityResult办法即可实现获取用户操作返回的需要。然而目前在MAUI中实现并非如此简略,因为MAUI中没有定义好的ActivityResultCallback类。上面咱们来编写代码。
二、代码编写
1、实现代码
在上文代码的根底上,咱们持续在MainActivity.cs增加代码
public class MainActivity : MauiAppCompatActivity { internal static MainActivity Instance { get; private set; } internal static ActivityResultLauncher PickMultipleMedia { get; private set; } public TaskCompletionSource<Dictionary<string, string>> PickImageTaskCompletionSource { set; get; } protected override void OnCreate(Bundle savedInstanceState) { Instance = this; PickMultipleMedia = Instance.RegisterForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(100), new ActivityResultCallback()); base.OnCreate(savedInstanceState); } private class ActivityResultCallback : Java.Lang.Object, IActivityResultCallback { public void OnActivityResult(Java.Lang.Object p0) { if (!p0.Equals(new Android.Runtime.JavaList())) { var list = (Android.Runtime.JavaList)p0; if (!list.IsEmpty) { var uris = list.Cast<Uri>().ToList(); var fileList = Instance.GetImageDicFromUris(uris); Instance.PickImageTaskCompletionSource.SetResult(fileList); } else { Instance.PickImageTaskCompletionSource.SetResult(new Dictionary<string, string>()); } } } } }
咱们创立了一个动态的ActivityResultLauncher 类型的PickMultipleMedia,并在OnCreate办法中通过RegisterForActivityResult注册,办法第一个参数类型为ActivityResultContract,咱们设置了100个图片的限度,第二个参数是一个IActivityResultCallback类型的Callback。因为默认没有提供,咱们须要本人定义。
留神:咱们的callback办法在继承IActivityResultCallback接口的同时,还必须显示的继承Java.Lang.Object,否则会报错。
咱们仅需实现OnActivityResult办法即可,这里留神,办法的参数为Java.Lang.Object类型,有些文章会让咱们将Java.Lang.Object强制转换为ActivityResult类型,而后再获取其中的文件Uri,然而通过测试目前在MAUI中不可用,转换之后永远为null。通过屡次尝试后,确定多选照片返回的类型为Android.Runtime.JavaList。
我这里通过 !p0.Equals(new Android.Runtime.JavaList()) 判断用户没有抉择任何照片的场景。最初通过遍历,应用之前写好的GetImageDicFromUris办法获取所有文件的内容。
2、测试代码
咱们在上文的IPhotoPickerService.cs接口中扩大一个GetImageAsync4不便咱们对几种实现形式进行比照。
public class AndroidPhotoPickerService : IPhotoPickerService { ... public Task<Dictionary<string, string>> GetImageAsync4() { MainActivity.PickMultipleMedia.Launch(new PickVisualMediaRequest.Builder() .SetMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.Instance).Build()); MainActivity.Instance.PickImageTaskCompletionSource = new TaskCompletionSource<Dictionary<string, string>>(); return MainActivity.Instance.PickImageTaskCompletionSource.Task; } }
这里应用的办法非常简单,参考下面JAVA的写法即可
JAVA代码pickMultipleMedia.launch(new PickVisualMediaRequest.Builder() .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE) .build());
在Index.razor中增加一个MListItem
<MList> ... <MListItem OnClick="GetImageAsync4"> <MListItemContent> <MListItemTitle>Jetpack-PickMultipleVisualMedia</MListItemTitle> </MListItemContent> </MListItem></MList>
三、演示成果
留神界面的变动,这里是以半屏弹出的形式展现的。
如果你对咱们的 MASA Framework 感兴趣,无论是代码奉献、应用、提 Issue,欢送分割咱们
WeChat:MasaStackTechOps
QQ:7424099