flutter总结 - 插件plugin

一、flutter调用原生并获取返回

主要通过MethodChannel建立连接。

1.1 flutter部分

初始化

//调用原生的通道,"flutterplugindemo"要和原生部分一致
_channel = MethodChannel('flutterplugindemo');

带参调用

    //入参
    Map<dynamic, dynamic> map = Map();
    map["param"] = "222";
    await _channel.invokeMethod("sayHello", map);

回参

    //等待回参
    Map<dynamic, dynamic> response =
        await _channel.invokeMethod("sayHello", map);
    print("返回" + response.toString());

示例

import 'dart:async';
import 'package:flutter/services.dart';

class Flutterplugindemo {
  MethodChannel _channel;

  Flutterplugindemo() {
    init();
  }

  init() {
    //调用原生的通道,"flutterplugindemo"要和原生部分一致
    _channel = MethodChannel('flutterplugindemo');
  }

  Future<Map<dynamic, dynamic>> sayHello() async {
    //入参
    Map<dynamic, dynamic> map = Map();
    map["param"] = "222";

    //等待回参
    Map<dynamic, dynamic> response =
        await _channel.invokeMethod("sayHello", map);
    print("返回" + response.toString());
    return response;
  }
}

1.2 原生部分

初始化

        MethodChannel channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(),
                "flutterplugindemo");
        channel.setMethodCallHandler(this);

会产生onMethodCall回调用来接收flutter调用

获取参数

            Map<String, Object> map = (Map<String, Object>) call.arguments;
            Log.i("FlutterplugindemoPlugin", "入参:map=" + map.toString());

返回参数

            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("1111", "33333");
            result.success(resultMap);

示例

package com.example.flutterplugindemo.demo;

import android.util.Log;

import androidx.annotation.NonNull;

import java.util.HashMap;
import java.util.Map;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;

public class DemoPlugin implements MethodChannel.MethodCallHandler {

    public void onAttachedToEngine(@NonNull FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
        MethodChannel channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(),
                "flutterplugindemo");
        channel.setMethodCallHandler(this);
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
        if (call.method.equals("sayHello")) {
            Map<String, Object> map = (Map<String, Object>) call.arguments;
            Log.i("FlutterplugindemoPlugin", "入参:map=" + map.toString());

            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("1111", "33333");
            result.success(resultMap);
        } else {
            result.notImplemented();
        }
    }

    public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding binding) {
    }
}

1.3 使用

直接引入调用即可

flutterplugindemo.sayHello();

示例

import 'package:flutter/material.dart';
import 'package:flutterplugindemo/flutter_plugin_webview.dart';
import 'package:flutterplugindemo/flutterplugindemo.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Flutterplugindemo flutterplugindemo;

  @override
  void initState() {
    super.initState();
    flutterplugindemo = Flutterplugindemo();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Column(
          children: <Widget>[
            RaisedButton(
              onPressed: () {
                flutterplugindemo.sayHello();
              },
              child: Text("点我"),
            ),
          ],
        ),
      ),
    );
  }
}

二、原生调用flutter并返回

2.1 原生部分

初始化

        channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(),
                "flutterplugindemo");

带参调动flutter并获取回参

            Map<String, Object> map = new HashMap<>();
            map.put("5555", "6666");
            channel.invokeMethod("sayhello2", map, new MethodChannel.Result() {
                @Override
                public void success(Object result) {
                    Map<String, Object> resultMap = (Map<String, Object>) result;
                    Log.i("FlutterplugindemoPlugin", "回参:map=" + resultMap.toString());
                }

                @Override
                public void error(String errorCode, String errorMessage, Object errorDetails) {

                }

                @Override
                public void notImplemented() {

                }
            });

示例

package com.example.flutterplugindemo.demo;

import android.util.Log;

import androidx.annotation.NonNull;

import java.util.HashMap;
import java.util.Map;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;

public class DemoPlugin implements MethodChannel.MethodCallHandler {
    private EventChannel.EventSink eventSink;
    private MethodChannel channel;

    public void onAttachedToEngine(@NonNull FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
        channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(),
                "flutterplugindemo");
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
        if (call.method.equals("sendEvent2")) {
            Map<String, Object> map = new HashMap<>();
            map.put("5555", "6666");
            channel.invokeMethod("sayhello2", map, new MethodChannel.Result() {
                @Override
                public void success(Object result) {
                    Map<String, Object> resultMap = (Map<String, Object>) result;
                    Log.i("FlutterplugindemoPlugin", "回参:map=" + resultMap.toString());
                }

                @Override
                public void error(String errorCode, String errorMessage, Object errorDetails) {

                }

                @Override
                public void notImplemented() {

                }
            });
        } else {
            result.notImplemented();
        }
    }

    public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding binding) {
    }
}

2.2 flutter部分

初始化

    _channel = MethodChannel('flutterplugindemo');
    _channel.setMethodCallHandler(handler);

获取参数和返回结果

  Future<dynamic> handler(MethodCall call) async {
    if (call.method == "sayhello2") {
      Map<dynamic, dynamic> map = call.arguments;
      print(map);

      Map<dynamic, dynamic> map2 = Map();
      map2["param"] = "4444";
      return map2;
    }
  }

示例

import 'dart:async';

import 'package:flutter/services.dart';

class Flutterplugindemo {
  MethodChannel _channel;

  Flutterplugindemo() {
    init();
  }

  init() {
    //调用原生的通道,"flutterplugindemo"要和原生部分一致
    _channel = MethodChannel('flutterplugindemo');
    _channel.setMethodCallHandler(handler);
  }

  Future<dynamic> handler(MethodCall call) async {
    if (call.method == "sayhello2") {
      Map<dynamic, dynamic> map = call.arguments;
      print(map);

      Map<dynamic, dynamic> map2 = Map();
      map2["param"] = "4444";
      return map2;
    }
  }
}

三、原生发送事件通知flutter

3.1 flutter部分

注册监听

    //监听原生事件
    EventChannel("flutter_plugin_event_2")
        .receiveBroadcastStream()
        .listen(eventListener);

接收事件

  //接收事件
  void eventListener(dynamic event) {
    Map<dynamic, dynamic> map = event;
    print("event" + map.toString());
  }

示例

import 'dart:async';

import 'package:flutter/services.dart';

class Flutterplugindemo {
  MethodChannel _channel;

  Flutterplugindemo() {
    init();
  }

  init() {
    //监听原生事件,"flutter_plugin_event_2"要和原生部分一致
    EventChannel("flutter_plugin_event_2")
        .receiveBroadcastStream()
        .listen(eventListener);
  }

  //接收事件
  void eventListener(dynamic event) {
    Map<dynamic, dynamic> map = event;
    print("event" + map.toString());
  }
}

3.2 原生部分

初始化

        EventChannel eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(),
                "flutter_plugin_event_2");
        eventChannel.setStreamHandler(streamHandler);
    private EventChannel.StreamHandler streamHandler = new EventChannel.StreamHandler() {
        @Override
        public void onListen(Object arguments, EventChannel.EventSink events) {
            eventSink = events;
        }

        @Override
        public void onCancel(Object arguments) {
        }
    };

发送事件

            //发送事件
            if (eventSink != null) {
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("333", "44444");
                eventSink.success(resultMap);
            }

示例

package com.example.flutterplugindemo.demo;

import android.util.Log;

import androidx.annotation.NonNull;

import java.util.HashMap;
import java.util.Map;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;

public class DemoPlugin implements MethodChannel.MethodCallHandler {
    private EventChannel.EventSink eventSink;

    public void onAttachedToEngine(@NonNull FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
        EventChannel eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(),
                "flutter_plugin_event_2");
        eventChannel.setStreamHandler(streamHandler);
    }

    private EventChannel.StreamHandler streamHandler = new EventChannel.StreamHandler() {
        @Override
        public void onListen(Object arguments, EventChannel.EventSink events) {
            eventSink = events;
        }

        @Override
        public void onCancel(Object arguments) {
        }
    };

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
        if (call.method.equals("sendEvent")) {
            //发送事件
            if (eventSink != null) {
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("333", "44444");
                eventSink.success(resultMap);
            }
        } else {
            result.notImplemented();
        }
    }

    public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding binding) {
    }
}

四、flutter使用原生view

主要使用AndroidView封装实现

4.1 flutter部分

初始化

if (defaultTargetPlatform == TargetPlatform.android) {
      //原生页面
      return AndroidView(
        viewType: "nativeweb",
        onPlatformViewCreated: onPlatformViewCreated,
        creationParamsCodec: StandardMessageCodec(),
      );
    }

封装调用原生方法的controller

typedef void WebViewCreatedCallback(WebController controller);
//调用原生方法的Controller
class WebController {
  MethodChannel _channel;

  WebController.init(int id) {
    _channel = MethodChannel("nativeweb_$id");
  }
  //调用原生方法
  Future<void> loadUrl(String url) async {
    assert(url != null);
    await _channel.invokeMethod("loadUrl", url);
  }
}
  Future<void> onPlatformViewCreated(int id) async {
    if (widget.onWebCreated == null) {
      return;
    }
    widget.onWebCreated(WebController.init(id));
  }

示例

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

typedef void WebViewCreatedCallback(WebController controller);

class NativeWeb extends StatefulWidget {
  final WebViewCreatedCallback onWebCreated;

  NativeWeb({this.onWebCreated});

  @override
  State<StatefulWidget> createState() => NativeWebState();
}

class NativeWebState extends State<NativeWeb> {
  @override
  Widget build(BuildContext context) {
    if (defaultTargetPlatform == TargetPlatform.android) {
      //原生页面
      return AndroidView(
        viewType: "nativeweb",
        onPlatformViewCreated: onPlatformViewCreated,
        creationParamsCodec: StandardMessageCodec(),
      );
    } else {
      return Text("$defaultTargetPlatform 不支持此插件");
    }
  }

  Future<void> onPlatformViewCreated(int id) async {
    if (widget.onWebCreated == null) {
      return;
    }
    widget.onWebCreated(WebController.init(id));
  }
}

//调用原生方法的Controller
class WebController {
  MethodChannel _channel;

  WebController.init(int id) {
    _channel = MethodChannel("nativeweb_$id");
  }
  //调用原生方法
  Future<void> loadUrl(String url) async {
    assert(url != null);
    await _channel.invokeMethod("loadUrl", url);
  }
}

4.2 原生部分

初始化
创建PlatformViewFactory、PlatformView

    public void onAttachedToEngine(FlutterPlugin.FlutterPluginBinding binding) {
        binding.getPlatformViewRegistry()
                .registerViewFactory("nativeweb", new WebFactory(binding));
    }
    private FlutterPlugin.FlutterPluginBinding flutterPluginBinding;

    public WebFactory(FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
        super(StandardMessageCodec.INSTANCE);
        this.flutterPluginBinding = flutterPluginBinding;
    }

    @Override
    public PlatformView create(Context context, int viewId, Object args) {
        return new FlutterWeb(context,flutterPluginBinding,viewId);
    }

创建view
在FlutterWeb.java中。

    /**
     * 创建view
     * @return
     */
    @Override
    public View getView() {
        return webView;
    }

封装调用方法

        channel  = new MethodChannel(binding.getBinaryMessenger(),"nativeweb_"+id);
        channel.setMethodCallHandler(this);
    /**
     * 调用方法
     * @param call
     * @param result
     */
    @Override
    public void onMethodCall(MethodCall call, MethodChannel.Result result) {
        switch (call.method){
            case "loadUrl":
                String url = call.arguments.toString();
                webView.loadUrl(url);
                break;
            default:
                result.notImplemented();
        }
    }

示例
WebViewPlugin.java

package com.example.flutterplugindemo.webview;

import io.flutter.embedding.engine.plugins.FlutterPlugin;

public class WebViewPlugin {
    public void onAttachedToEngine(FlutterPlugin.FlutterPluginBinding binding) {
        binding.getPlatformViewRegistry()
                .registerViewFactory("nativeweb", new WebFactory(binding));
    }

    public void onDetachedFromEngine(FlutterPlugin.FlutterPluginBinding binding) {

    }
}

WebFactory.java

package com.example.flutterplugindemo.webview;

import android.content.Context;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MessageCodec;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;

public class WebFactory extends PlatformViewFactory {

    private FlutterPlugin.FlutterPluginBinding flutterPluginBinding;

    public WebFactory(FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
        super(StandardMessageCodec.INSTANCE);
        this.flutterPluginBinding = flutterPluginBinding;
    }

    @Override
    public PlatformView create(Context context, int viewId, Object args) {
        return new FlutterWeb(context,flutterPluginBinding,viewId);
    }
}

FlutterWeb.java

package com.example.flutterplugindemo.webview;

import android.content.Context;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.platform.PlatformView;

public class FlutterWeb implements PlatformView , MethodChannel.MethodCallHandler{
    Context context;
    MethodChannel channel;

    WebView webView;

    public FlutterWeb(Context context,FlutterPlugin.FlutterPluginBinding binding, int id) {
        this.context = context;

        webView = getWebView(binding.getApplicationContext());

        channel  = new MethodChannel(binding.getBinaryMessenger(),"nativeweb_"+id);
        channel.setMethodCallHandler(this);
    }

    /**
     * 创建view
     * @return
     */
    @Override
    public View getView() {
        return webView;
    }

    @Override
    public void dispose() {

    }

    /**
     * 调用方法
     * @param call
     * @param result
     */
    @Override
    public void onMethodCall(MethodCall call, MethodChannel.Result result) {
        switch (call.method){
            case "loadUrl":
                String url = call.arguments.toString();
                webView.loadUrl(url);
                break;
            default:
                result.notImplemented();
        }
    }

    private WebView getWebView(Context context){
        WebView webView = new WebView(context);
        webView.setWebViewClient(new WebViewClient());
        webView.getSettings().setJavaScriptEnabled(true);
        return webView;
    }
}

4.3 使用

布局中直接使用即可

NativeWeb(onWebCreated: onWebCreated)

示例:

import 'package:flutter/material.dart';
import 'package:flutterplugindemo/flutter_plugin_webview.dart';
import 'package:flutterplugindemo/flutterplugindemo.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Flutterplugindemo flutterplugindemo;

  @override
  void initState() {
    super.initState();
    flutterplugindemo = Flutterplugindemo();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Column(
          children: <Widget>[
            Container(
              height: 500,
              child: NativeWeb(onWebCreated: onWebCreated),
            ),
          ],
        ),
      ),
    );
  }

  void onWebCreated(WebController webController) {
    webController.loadUrl("https://www.baidu.com/");
  }
}

五、参考

官网
git 示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值