本片利用Flutter Plugin 调用原生Android的相册墙的功能。
现有的和相机有关的库 有 image_picker 和camera
不过image_picker用起来像是普通的调用Android自带的拍照和相册(单选)功能,而camera好像是拍照功能(不太了解)。这些都不够炫酷,不如让我们来自己写插件。
最终效果是让Flutter实现Android的matisse功能,一款强大的相册墙,我自己开发的Android也在用matisse。
下面开始正题 ,放图
1.我们从Flutter中调用Android接口
2.Android调用matisse,选好图片之后
3.在ActivityResult回调中得到图片数据
4.再从Android发送数据到Flutter的接口(并不用result.success,因为是异步,只能我们单独再次发给它)
5.在Flutter中设置Stream实现监听
首先你得进AS,开启一个Plugin项目,对比着看下文,粘贴复制什么的,so easy。
implementation'com.zhihu.android:matisse:0.5.2-beta2'
implementation'com.github.bumptech.glide:glide:4.8.0'
implementation'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation'io.reactivex.rxjava2:rxjava:2.0.5'
implementation'com.tbruyelle.rxpermissions2:rxpermissions:0.9.3@aar'
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
Android用到的库和权限
我们从Flutter中调用Android接口:
platformVersion =await FlutterPluginShowImage.showImage;
FlutterPluginShowImage是插件的Flutter类,showImage是其中的方法
这里是 showImage方法
static Futureget showImage async{
await _channel.invokeMethod('showImage');
}
相当于发送 msg.what='showImage' 消息的Hanlder,
@Override
public void onMethodCall(MethodCall call,final Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
}else if(call.method.equals("showImage")){
Util.showImage(mContext);
}else {
result.notImplemented();
}
}
我把方法体封装在Util中了,至于为什么,可能是因为寂寞吧
public static void showImage(final Activity activity){
RxPermissions rxPermissions =new RxPermissions(activity);
rxPermissions.requestEach(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(new Consumer() {
@Override
public void accept(Permission permission)throws Exception {
if (permission.granted) {
openAlbum(activity);
return;
}
if (permission.shouldShowRequestPermissionRationale) {
Log.d(TAG,"intoPics: 用户不给权限");
return;
}
Log.d(TAG,"intoPics: ");
}
});
}
如果用户给读写的权限 ,用到了RXPermission,rxJava什么的,不会的可以无视,反正就是申请权限,并调用openAlbum(activity);
public static void openAlbum(Activity activity){
Matisse.from(activity)
.choose(MimeType.ofAll())//照片视频全部显示
.countable(true)//显示选择的数量
.maxSelectable(3)// 图片选择的最多数量
.gridExpectedSize(getPicWidth(activity) /3 -5)//图片显示在列表中的大小
.restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
.thumbnailScale(0.3f)// 缩略图的比例
.imageEngine(new MyGlideEngine())// 使用的图片加载引擎
.theme(R.style.Matisse_Zhihu)//主题
.capture(false)//是否提供拍照功能
.forResult(23);// 设置作为标记的请求码
}
以上就是调用matisse的打开相册墙的代码。其中的activity或者context的数据都可以从
registrar获取, eg : mContext=registrar.activity();//registrar是自动生成方法的参数
registrar.addActivityResultListener(new PluginRegistry.ActivityResultListener() {
@Override
public boolean onActivityResult(int requestCode,int resultCode, Intent data) {
if (requestCode ==23 && resultCode ==RESULT_OK) {//与请求码对应,测试随便取了个值
List <Uri>mSelected = Matisse.obtainResult(data);
List <String>uriList=new ArrayList<>();
for(Uri uri :mSelected){
Log.d(TAG,"onActivityResult: uri="+uri+"getPath"+uri.toString());
uriList.add(uri.toString());
};
channel.invokeMethod("AndroidToPics",uriList);
}
return true;
}
});
回调ActivityResult也是要用到registrar,Uri似乎不在参数传递范围内,所以用List<String>重新包装。
channel.invokeMethod("AndroidToPics",uriList);就是向发送msg.what的“AndroidToPics”的消息,
uriList就相当于msg.obj;
_channel.setMethodCallHandler(_handler);
在Flutter中设置这个回调,
static Future_handler(MethodCall methodCall) {
if (methodCall.method=="AndroidToPics") {
var list= methodCall.arguments;
_responseController.add(list);//
}
return Future.value(true);
}
如果这个地方不懂的话,就去研究一下Stream,这里可以当做一个简单的监听事件,当add之后,listener就有了响应
static StreamController_responseController = new StreamController.broadcast();
static Streamget get response =>_responseController.stream;
Flutter中声明一个StreamController,加一个response 方法让main.dart获取
FlutterPluginShowImage.response.listen((data) {
print(“success”);
print(data);
});
获取到了Stream,调用Stream.listener方法在main.dart中设置监听,当你add之后,这个地方便有了回应。你的数据信息便出来了。
activity是从Android获取的,下面两个是从Flutter获取的。数据有了,剩下的你懂得。
至此,完成任务.
网友评论