Flutter Plugin 交互

2019-03-07  本文已影响0人  寄吻_3914

本片利用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获取的。数据有了,剩下的你懂得。

至此,完成任务.

上一篇下一篇

猜你喜欢

热点阅读