一、背景
项目开发需要将h5开发的地图功能切换成由native开发的地图功能,现在想要在flutter的widget中嵌入AndroidView去开发地图功能。
二、使用方法
目录中新建几个文件:
1、自定义的view文件
public class MyView implements PlatformView , MethodChannel.MethodCallHandler{
private final TextView natvieTextView;
Context context;
public MyView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) {
this.context = context;
TextView myNativeView = new TextView(context);
myNativeView.setText("我是来自Android的原生TextView");
if (params.containsKey("myContent")) {
String myContent = (String) params.get("myContent");
myNativeView.setText(myContent);
}
this.natvieTextView = myNativeView;
MethodChannel methodChannel = new MethodChannel(messenger, "com.focus_eloan.directsale/mapView_" + id);
methodChannel.setMethodCallHandler(this);
}
@Override
public View getView() {
return natvieTextView;
}
@Override
public void dispose() {
}
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if ("setText".equals(call.method)) {
String text = (String) call.arguments;
natvieTextView.setText(text);
result.success(null);
}
}
}
2、MyViewFactory文件
public class MyViewFactory extends PlatformViewFactory {
private final BinaryMessenger messenger;
public MyViewFactory(BinaryMessenger messenger) {
super(StandardMessageCodec.INSTANCE);
this.messenger = messenger;
}
@SuppressWarnings("unchecked")
@Override
public PlatformView create(Context context, int id, Object args) {
Map<String, Object> params = (Map<String, Object>) args;
return new MyView(context, messenger, id, params);
}
}
3、MyViewFlutterPlugin文件
public class MyViewFlutterPlugin {
private static String NATIVE_VIEW_TYPE_ID = "com.focus_eloan.directsale/mapView";
//旧方法
public static void registerWith(PluginRegistry registry) {
final String key = MyViewFlutterPlugin.class.getCanonicalName();
if (registry.hasPlugin(key)) {
return;
}
PluginRegistry.Registrar registrar = registry.registrarFor(key);
registrar.platformViewRegistry().registerViewFactory(NATIVE_VIEW_TYPE_ID, new MyViewFactory(registrar.messenger()));
}
//新方法
public static void registerWith(FlutterEngine flutterEngine) {
flutterEngine.getPlatformViewsController().getRegistry().registerViewFactory(NATIVE_VIEW_TYPE_ID, new MyViewFactory(flutterEngine.getDartExecutor().getBinaryMessenger()));
}
}
4、MainActivity中添加
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
MyViewFlutterPlugin.registerWith(flutterEngine);
}
其中需要注意,由于新版本的flutter环境下,只能拿到FlutterEngine,只能通过registerWith(FlutterEngine flutterEngine)方法进行注册,registerWith(PluginRegistry registry)的老方法暂时不用了,新方法自测是可以使用的。
方法来源于:https://stackoverflow.com/questions/61869895/is-it-possible-to-use-platformview-without-adding-android-plugin-in-flutter
5、flutter端的修改
需要注意viewType需要和MyViewFlutterPlugin中注册的viewType保持一致。
Container(
width: double.infinity,
height: double.infinity,
child: AndroidView(
viewType: 'com.focus_eloan.directsale/mapView',
creationParams: {
"myContent": "通过参数传入的文本内容,I am 原生view",
},
creationParamsCodec: const StandardMessageCodec(),
onPlatformViewCreated: this.onMyViewCreated,
),
);
MethodChannel _channel;
void onMyViewCreated(int id) {
_channel = new MethodChannel('com.focus_eloan.directsale/mapView_$id');
}
通过_channel对象可以和Android端的自定义view进行交互