美文网首页
Flutter嵌入Native组件

Flutter嵌入Native组件

作者: 初见破晓 | 来源:发表于2019-02-22 17:31 被阅读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组件

    图9

    9、问题

    点击input框,软件盘不会弹出

    ·

    相关文章

      网友评论

          本文标题:Flutter嵌入Native组件

          本文链接:https://www.haomeiwen.com/subject/xscdyqtx.html