Flutter嵌入Native组件
2019-02-22 本文已影响4人
初见破晓
上一篇文章写了怎么在Flutter中调用Native的方法,同时Flutter也提供了嵌入原生Native组件的方法
1、创建一个插件
在android studio中创建了一个Flutter Plugin。这里直接在一个Flutter项目中创建了一个Plugin,主要尝试使用本地依赖的方式引入
图1
这里遇到了一个坑,我创建完了一个插件之后,AS卡死了, 随后我在项目的根目录下执行了flutter packages get 之后, 并重启IDE之后才解决
2、解决报错
我在一个Flutter项目中创建了一个本地的Plugin,项目结构大概是这个样子,但是有报错。是插件中的测试文件找不到Flutter相关的包,我在插件的pubspec.yaml加入一行,如下图3, get packages 之后发现只有找不到MyApp了,我确实没有MyApp,删掉就好。
图2图3 图4
3、编写Android代码
还是在Android端编写代码(因为我根本不会ios),Android端代码也有报错,是找不到Flutter相关的jar包,我用了好多种方式,最后,直接用AS打开了插件下的example中的android项目。
长时间build之后,项目没有报错,开了两个AS,除了风扇有点响之外没有其他的异常出现。
图5
图6
4、关联主项目
在主项中的配置文件添加插件的本地路径,然后flutter packages get
图7
到此位置、配置工作已经完成了,接下来就可以写代码了
5、创建Native组件
首先在远端创建一个view,这个我们需要Flutter提供的PlatformViewFactory
class WebViewPlatformViewFactory extends PlatformViewFactory implements MethodChannel.MethodCallHandler {
private WebView mWebView;
private PluginRegistry.Registrar mRegistrar;
WebViewPlatformViewFactory(PluginRegistry.Registrar registrar) {
super(StandardMessageCodec.INSTANCE);
mRegistrar = registrar;
}
@Override
public PlatformView create(final Context context, int id, Object o) {
final MethodChannel channel = new MethodChannel(mRegistrar.messenger(), "webview_plugin_" + id);
channel.setMethodCallHandler(this);
mWebView = new WebView(mRegistrar.context());
mWebView.setWebViewClient(new WebViewClient());
return new PlatformView() {
@Override
public View getView() {
return mWebView;
}
@Override
public void dispose() {
}
};
}
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
String method = methodCall.method;
switch (method) {
case "loadUrl":
mWebView.loadUrl(methodCall.arguments.toString());
result.success(null);
break;
default:
result.notImplemented();
break;
}
}
}
- PlatformViewFactory 用于创建跨平台的视图
- MethodChannel 用于消息通讯
- PlatformView 向Flutter返回一个Native组件
6、创建Flutter组件
在Flutter端封装一个叫webview的组件
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class WebView extends StatefulWidget {
final ControllerCallBack controller;
WebView({Key key, this.controller}) : super(key: key);
@override
_WebViewState createState() => _WebViewState();
}
class _WebViewState extends State<WebView> {
@override
Widget build(BuildContext context) {
return Container(
child: AndroidView(
onPlatformViewCreated: _onPlatformViewCreated,
creationParamsCodec: StandardMessageCodec(),
viewType: "org.tiny.webviewplugin.webview",
),
);
}
void _onPlatformViewCreated(int id) {
_WebViewController controller = _WebViewController._(id);
widget.controller(controller);
}
}
class _WebViewController {
MethodChannel _channel;
_WebViewController._(int id) {
_channel = MethodChannel('webview_plugin_$id');
}
void loadUrl(String url) async {
await _channel.invokeMethod("loadUrl", url);
}
}
typedef ControllerCallBack = Function(_WebViewController controller);
- onPlatformViewCreated 当view创建完成时调用,在这之后我们才能建立消息通道,调用远程视图
7、注册组件
Android 端进行组件的注册
public class WebviewPlugin {
/** Plugin registration. */
public static void registerWith(Registrar registrar) {
registrar.platformViewRegistry().registerViewFactory("org.tiny.webviewplugin.webview",
new WebViewPlatformViewFactory(registrar));
}
}
-
WebviewPlugin 其实是主项目引入这个插件时, 主项目就会自动的去调用WebviewPlugin 的 registerWith 方法,这个类是自动生成的。
图8
8、
Android端显示的webview组件
图99、问题
点击input框,软件盘不会弹出
·