精华内容
参与话题
问答
  • 1. Flutter 调用 Android 2. Android 通知 Flutter 3. Flutter 调用 iOS 4. iOS 通知 Flutter 项目地址 在 flutter 开发中一定会有需要和原生通信的情况 第一篇介绍的是 flutter 调用 Android 这篇是给刚刚入门或者...

    原生通信系列

    1. Flutter 调用 Android
    2. Android 通知 Flutter
    3. Flutter 调用 iOS
    4. iOS 通知 Flutter

    项目地址


    在 flutter 开发中一定会有需要和原生通信的情况

    第一篇介绍的是 flutter 调用 Android

    这篇是给刚刚入门或者刚刚接触原生调用的朋友们使用的,老鸟们或者英文强的朋友还是直接看官方文档比较好

    创建项目

    一般来说建议使用一个 plugin 作为一个单独的项目来将业务逻辑独立出去

    我这里使用命令行创建,事实上一律建议使用命令行创建,因为信息更加可见一些

    flutter create --template plugin  battle_power
    cd battle_power
    

    前面都是固定格式,最后面那个是插件名,根据你自己的需要来修改

    创建好的截图如下
    图片

    和开发 package 的时候不同,开发 plugin 需要打开 example/android 目录

    图片

    使用快捷的方式,或自己通过 Android Studio 的 open 打开项目

    图片
    等待完成

    图片
    接着就可以开始开发了,

    默认生成了一个 java 文件,可以称之为插件的主文件

    流程图

    图片

    乱画的…随便看看就好

    android 端

    package com.example.battlepower;
    
    import io.flutter.plugin.common.MethodCall;
    import io.flutter.plugin.common.MethodChannel;
    import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
    import io.flutter.plugin.common.MethodChannel.Result;
    import io.flutter.plugin.common.PluginRegistry.Registrar;
    
    /** BattlePowerPlugin */
    public class BattlePowerPlugin implements MethodCallHandler {
      /** Plugin registration. */
      public static void registerWith(Registrar registrar) {
        final MethodChannel channel = new MethodChannel(registrar.messenger(), "battle_power"); //这里对应dart端的 MethodChannel
        channel.setMethodCallHandler(new BattlePowerPlugin());
      }
    
      @Override
      public void onMethodCall(MethodCall call, Result result) {
        if (call.method.equals("getPlatformVersion")) { // 对应dart端 invoceMethod
          result.success("Android " + android.os.Build.VERSION.RELEASE);
        } else {
          result.notImplemented();
        }
      }
    }
    

    当然如果你对于 kotlin 比较喜欢也可以使用 kotlin 进行插件开发

    如果你不会 Java/Kotlin ,甚至不会原生开发,只能说你进入了一个全新的领域,希望你一切都好吧…,建议你先系统的学习下 android 再来

    dart 端

    import 'dart:async';
    
    import 'package:flutter/services.dart';
    
    class BattlePower {
      static const MethodChannel _channel =
          const MethodChannel('battle_power');
    
      static Future<String> get platformVersion async {
        final String version = await _channel.invokeMethod('getPlatformVersion');
        return version;
      }
    }
    
    

    dart 端和 java 端是一一对应的

    交互

    调用

    由 dart 端使用_channel.invokeMethod调用,这个方法的参数是方法名和一个可选参数

    返回值是一个Future<dynamic> 因为 java 端的调用是不可预知的,所以是异步的

    换句话说,无论结果是对是错你在 java 端都需要有返回值,否则 dart 端会挂起

    查看 java 端文档

    图片

    可选参数

    可选参数是 dart 中的一个语法特点,方法的签名中通过[]包裹的为匿名可选参数,通过{}包裹的为命名可选参数

    而 channel 中的这个方法的完整实现如下

    结果返回

    查看文档

    图片

    不同于传统的同步方法调用,java 端需要使用result.success(object)来返回一个结果给 dart

    使用result.notImplemented();来表示未定义的方法,dart 端会接收到一个异常

    返回一个错误result.error(String code,String msg,Throwable throwable)

    调用过程分析

      Future<dynamic> invokeMethod(String method, [dynamic arguments]) async {
        assert(method != null);
        final dynamic result = await BinaryMessages.send(
          name,
          codec.encodeMethodCall(MethodCall(method, arguments)),
        );
        if (result == null)
          throw MissingPluginException('No implementation found for method $method on channel $name');
        return codec.decodeEnvelope(result);
      }
    
    

    method 是必填参数, 这个和 java 端的监听一一对应

    第二个是一个可选一个参数,这个参数可传递任意参数,但只能有一个,然后会通过内部的 codec 进行编码后传递给 native 端,这个 codec 对象是创建MethodChannel时创建的
    图片
    有一个默认类型为StandardMethodCodec,这个类型后面会解析,先略过


      public static void registerWith(Registrar registrar) {
        final MethodChannel channel = new MethodChannel(registrar.messenger(), "battle_power");
        channel.setMethodCallHandler(new BattlePowerPlugin());
      }
    

    在 java 端使用这类代码来注册插件

    
      @Override
      public void onMethodCall(MethodCall call, Result result) {
        if (call.method.equals("getPlatformVersion")) {
          result.success("Android " + android.os.Build.VERSION.RELEASE);
        } else {
          result.notImplemented();
        }
      }
    

    这里的代码是用来监听回调的,当 dart 调用invokeMethod这里会被触发

    比如getPlatformVersion是一个没有传参数的方法, 直接返回了 Android os 对应的版本号

    这样 dart 在 java 端result.success调用后就会 返回版本号

    StandardMethodCodec 解析

    这个类也是在两端都有的一个类, 通常来说就是作为发送端负责编码, 作为接受端负责解码

    作为一个内置类,其中做了一些"自动"的转码过程,将原生类型映射为 dart 类型 或者反过来映射

    查看文档

    图片

    这里代表了基础的映射关系 也就是说 你在 invokeMethod 时,参数会被映射为右边的原生类型
    如果这里没有的类型就是不支持的类型,建议不要使用,否则会抛出无法解码的异常

    当然有正向映射,也会有对应的反向映射,也就是说, 你在 java 中作为结果返回的类型在 dart 端也会被映射为 dart 对应类型

    当然这个编解码器也可以自定义,基于二进制扩展即可,不过这个不属于基础的应用篇,暂时先不做

    自定义

    前面是自动生成的方法和签名

    现在自己添加一个带参数的方法

    dart

      static Future<int> requestNativeAdd(int x, int y) async {
        int result = await _channel.invokeMethod('add', {"x": x, "y": y});
        return result;
      }
    

    java

        @Override
        public void onMethodCall(MethodCall call, Result result) {
            switch (call.method) {
                case "getPlatformVersion":
                    result.success("Android " + android.os.Build.VERSION.RELEASE);
                    break;
                case "add":
                    Integer x = call.argument("x");
                    Integer y = call.argument("y");
                    if (x != null && y != null) {
                        result.success(x + y);
                    } else {
                        result.error("1", "不能为空", null);
                    }
                    break;
                default:
                    result.notImplemented();
                    break;
            }
        }
    

    方法很简单,传入一个 x 一个 y,然后 java 端加完返回回来

    这样一个简单的自定义就完成了


    你以为就这样结束了?

    请看第二篇 android 通知 flutter

    展开全文
  • 前言本文主要给大家介绍了关于Flutter调用Android和iOS原生代码的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧分3个大步骤:1.在flutter中调用原生方法2.在Android中实现被调用的方法...

    前言

    本文主要给大家介绍了关于Flutter调用Android和iOS原生代码的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

    分3个大步骤:

    1.在flutter中调用原生方法

    2.在Android中实现被调用的方法

    3.在iOS中实现被调用的方法

    在flutter中调用原生方法

    场景,这里你希望调用原生方法告诉你一个bool值,这个值的意义你可以随意定,这里表示的意义是是否是中国用户。

    你可以在flutter中设计好要调用的方法名称,这里就叫

    isChinese

    请注意:

    在flutter中要调用原生代码需要通过通道传递消息,在flutter端就是MethodChannel。

    所以我们这里的做法是,在flutter 端创建一个自己命名的通道:

    const platform = const MethodChannel("com.test/name");

    这里的名字 com.test/name 你可以随便取。

    讲解一下:

    你可能有疑问了,我们自作主张在flutter端创建的通道,怎么就能告诉Android和iOS端到底该怎么调用呢?

    你这个问题问得极好,这里啊先告诉你,等下我们还要分别在两端创建和这个通道同名的通道。

    敲黑板了:

    此时你知道了,我们要在三端分别有一个通道了吧,而且这三个通道是同名的,所以就能连接起来了。

    不过这里还是先把flutter端的代码写完,然后我们再去分别设置android和iOS端的代码吧。go!

    我们在flutter中的代码如下:

    Future isEuropeUser() async {

    // Native channel

    const platform = const MethodChannel("com.test/name"); //分析1

    bool result = false;

    try {

    result = await platform.invokeMethod("isChinese"); //分析2

    } on PlatformException catch (e) {

    print(e.toString());

    }

    return result;

    }

    还是分析一下:

    分析1: 创建一个我们自定义的channel。

    分析2: 用channel发送调用消息到原生端,调用方法是:isChinese

    好了,flutter端相信你也觉得很简单了,接下来我们来看下android端怎么搞。

    在Android中实现被调用的方法

    我建议你在Android studio编写Android端代码哦,因为这样有良好的代码提示和头文件引入。不过你要是有办法做到同样的效果,啥IDE俺都不在乎。

    在flutter项目文件夹里的Android文件夹中有一个 MainActivity.java文件,不要告诉我你找不到啊。

    我先告诉你等下就在MainActivity里注册我们的Android端插件。嘿嘿,现在先去写我们的Android端插件吧。

    代码我一次贴出来了,反正也不多。

    public class FlutterNativePlugin implements MethodChannel.MethodCallHandler {

    public static String CHANNEL = "com.test/name"; // 分析1

    static MethodChannel channel;

    private Activity activity;

    private FlutterNativePlugin(Activity activity) {

    this.activity = activity;

    }

    public static void registerWith(PluginRegistry.Registrar registrar) {

    channel = new MethodChannel(registrar.messenger(), CHANNEL);

    FlutterNativePlugin instance = new FlutterNativePlugin(registrar.activity());

    channel.setMethodCallHandler(instance);

    }

    @Override

    public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) { // 分析 2

    if (methodCall.method.equals("isChinese")) {

    boolean isChinese = true;

    result.success(isEuropean); // 分析3

    }

    else {

    result.notImplemented();

    }

    }

    }

    分析:

    分析1: 注意这里的插件名字要和flutter中的一样

    分析2:onMethodCall这个方法是插件的回调,这里我们根据方法名isChinese判断调用的方法,然后实现我们的操作就行了。

    分析3:这里直接返回了true,因为这只是个例子,而你应该换成你自己的逻辑哦。

    我们的插件写好了,回到MainActivity.java中进行注册。

    看下代码:

    public class MainActivity extends FlutterActivity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    GeneratedPluginRegistrant.registerWith(this);

    registerCustomPlugin(this);

    }

    private void registerCustomPlugin(PluginRegistry registrar) {

    FlutterNativePlugin.registerWith(registrar.registrarFor(FlutterNativePlugin.CHANNEL));

    }

    }

    恭喜恭喜,Android端完成了。

    //

    接下来我们搞一下iOS端:

    在iOS中实现被调用的方法

    iOS中我建议你在xcode中编写代码哦。因为这样会有良好的提示。

    我先告诉你要改那些文件:

    用xcode打开iOS工程后,在Runner文件夹下有AppDelegate文件。

    我们等下就在这里进行注册我们的插件。

    那么我们先写我们的插件代码吧:

    FlutterNativePlugin.h

    \#import

    #import

    NS_ASSUME_NONNULL_BEGIN

    @interface FlutterNativePlugin : NSObject

    @end

    NS_ASSUME_NONNULL_END

    FlutterNativePlugin.m

    #import "FlutterNativePlugin.h"

    #import "CountryUtils.h"

    @implementation FlutterNativePlugin

    + (void)registerWithRegistrar:(NSObject*)registrar {

    FlutterMethodChannel* channel =

    [FlutterMethodChannel methodChannelWithName:@"com.test/name"

    binaryMessenger:[registrar messenger]];

    FlutterNativePlugin* instance = [[FlutterNativePlugin alloc] init];

    [registrar addMethodCallDelegate:instance channel:channel];

    }

    - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {

    if ([@"isEuropeUser" isEqualToString:call.method]) {

    result([NSNumber numberWithBool:YES]);

    } else {

    result(FlutterMethodNotImplemented);

    }

    }

    @end

    分析:

    这里也是和android一个德行,分为注册和方法回调两部分。但是你可能发现了这里的通道是FlutterMethodChannel,这个不用大惊小怪,flutter也是用和Android上的MethodChannel不同类名类区分这两个平台的。只是名字不同而已。

    该在iOS上注册了:

    在 AppDelegate.m类的如下方法添加代码就行:

    - (BOOL)application:(UIApplication *)application

    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [GeneratedPluginRegistrant registerWithRegistry:self];

    [FlutterNativePlugin registerWithRegistrar: [self registrarForPlugin:@"FlutterNativePlugin"]];

    return [super application:application didFinishLaunchingWithOptions:launchOptions];

    }

    ///

    恭喜你,iOS端也设置完了。

    运行你的应用查看能不能调用成功吧。祝你顺利。

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

    展开全文
  • https://blog.csdn.net/zl18603543572/article/details/95983215 本文链接:...更多文章请查看 flutter从入门 到精通 本篇文章 中写到的是 flutter 调用Android 原生的 TextView 案例 添...

    https://blog.csdn.net/zl18603543572/article/details/95983215

    本文链接:https://blog.csdn.net/zl18603543572/article/details/95983215
    更多文章请查看 flutter从入门 到精通

    本篇文章 中写到的是 flutter 调用了Android 原生的 TextView 案例

    添加原生组件的流程基本上可以描述为:

    1 android 端实现原生组件PlatformView提供原生view
    2 android 端创建PlatformViewFactory用于生成PlatformView
    3 android 端创建FlutterPlugin用于注册原生组件
    4 flutter 平台嵌入 原生view
    1 创建原生组件

    创建在fLutter工程时会生成几个文件夹,lib是放flutter工程代码,android和ios文件夹分别是对应的双平台的原生工程。

    在这里直接打开Android工程目录,项目默认生成了GeneratedPluginRegistrant和MainActivity两个文件,GeneratedPluginRegistrant不要动,GeneratedPluginRegistrant是flutter中配制使用其他插件时,程序在编译时自动进行插件注册使用的类。

    在MainActivity的包下新建自定义View,Flutter的原生View不能直接继承自View,需要实现提供的PlatformView接口:

    public class TestTextView implements PlatformView r{
        
        private final TextView mTestTextView;
        
        /**
         * 
         * @param context
         * @param messenger
         * @param id
         * @param params  初始化时 flutter 传递过来的参数
         */
        TestTextView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) {
            //创建 TextView
            TextView lTextView = new TextView(context);
            lTextView.setText("Android的原生TextView");
            this.mTestTextView = lTextView;
            
            //flutter 传递过来的参数
            if (params!=null&&params.containsKey("content")) {
                String myContent = (String) params.get("content");
                lTextView.setText(myContent);
            }
        }
        
        @Override
        public View getView() {
            return mTestTextView;
        }
        
        @Override
        public void dispose() {
        
        }
        
    }

    2 创建PlatformViewFactory


    import android.content.Context;
    import java.util.Map;
    import io.flutter.plugin.common.BinaryMessenger;
    import io.flutter.plugin.common.StandardMessageCodec;
    import io.flutter.plugin.platform.PlatformView;
    import io.flutter.plugin.platform.PlatformViewFactory;

    public class TestViewFactory extends PlatformViewFactory {
        private final BinaryMessenger messenger;
        public TestViewFactory(BinaryMessenger messenger) {
            super(StandardMessageCodec.INSTANCE);
            this.messenger = messenger;
        }
        
        /**
         * 
         * @param context
         * @param id
         * @param args  args是由Flutter传过来的自定义参数
         * @return
         */
        @SuppressWarnings("unchecked")
        @Override
        public PlatformView create(Context context, int id, Object args) {
            //flutter 传递过来的参数
            Map<String, Object> params = (Map<String, Object>) args;
            //创建 TestTextView
            return new TestTextView(context, messenger, id, params);
            
        }

    3 创建Plugin并在ManActivity中注册插件


    /**
     * flutter 调用 android 原生view
     *
     */
    public class TestFluttertoAndroidTextViewPlugin {
        public static void registerWith(PluginRegistry registry) {
            //防止多次注册
            final String key = TestFluttertoAndroidTextViewPlugin.class.getCanonicalName();
            if (registry.hasPlugin(key)) return;
            //初始化 PluginRegistry
            PluginRegistry.Registrar registrar = registry.registrarFor(key);
            //设置标识
            registrar.platformViewRegistry().registerViewFactory("com.flutter_to_native_test_textview", new TestViewFactory(registrar.messenger()));
        }
    }

    MainActivity 中注册


    import android.os.Bundle

    import io.flutter.app.FlutterActivity
    import io.flutter.plugins.FlutterToAndroidPlugins
    import io.flutter.plugins.GeneratedPluginRegistrant

    class MainActivity: FlutterActivity() {
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //flutter 项目工程中默认生成的 
        GeneratedPluginRegistrant.registerWith(this)
        //这是我们新创建的插件
        TestFluttertoAndroidTextViewPlugin.registerWith(this)
       
      }

      override fun onDestroy() {
        super.onDestroy()

      }
    }


    4 flutter页面中嵌入android 原生Textview

    4.1 最简单的调用

    //这里设置的 viewType值与 android 中插件注册的标识 一至
    //registrar.platformViewRegistry().registerViewFactory("com.flutter_to_native_test_textview", new TestViewFactory(registrar.messenger()));
    mTextWidget = Container(
        height: 200,
        child: AndroidView(
            //设置标识 
            viewType: "com.flutter_to_native_test_textview",
         ),
      );

    @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Scaffold(
          appBar: appBar,
          //显示的页面
          body: mTextWidget,
        );
      }

    4.2 flutter 调用 原生view并传参数

              mTextWidget = Container(
                height: 200,
                child: AndroidView(
                  //标识
                  viewType: "com.flutter_to_native_test_textview",
                  creationParams: {
                    "content": "flutter 传入的文本内容",
                  },
                  //参数的编码方式
                  creationParamsCodec: const StandardMessageCodec(),
                ),
              );

    android 原生中的接收(只会接收一次)


    ... ...    

    TestTextView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) {
            ... ..
            //flutter 传递过来的参数
            if (params!=null&&!params.isEmpty()&&params.containsKey("content")) {
                String myContent = (String) params.get("content");
                lTextView.setText(myContent);
            }

        ... ...
        }

    4.3 flutter 更新 原生view 中的数据

    原生组件初始化的参数并不会随着setState重复赋值,可以通过MethodCall来实现更新数据。

    首先让原生view组件实现MethodCallHandler接口:

    public class TestTextView implements PlatformView , MethodChannel.MethodCallHandler{
        
        private final TextView mTestTextView;
        
        TestTextView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) {
            
            ... ...
            
            //com.flutter_to_native_test_view_ 是更新数据的通信标识
            MethodChannel methodChannel = new MethodChannel(messenger, "com.flutter_to_native_test_textview_" + id);
            methodChannel.setMethodCallHandler(this);
        }
        
        ... ...
        
        @Override
        public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {

           //updateText 是flutter 中调用的方法名称,可以随意定义
            if ("updateText".equals(methodCall.method)) {
                String text = (String) methodCall.arguments;
                this.mTestTextView .setText(text);
                //对flutter 的回调
                result.success(null);
            }
        }
    }

    flutter 中调用 android 原生view

      MethodChannel _channel;
      int viewId=0;

              mTextWidget = Container(
                height: 200,
                child: AndroidView(
                  //标识
                  viewType: "com.flutter_to_native_test_textview",
                  creationParams: {
                    "content": "flutter 传入的文本内容",
                  },
                  //参数的编码方式
                  creationParamsCodec: const StandardMessageCodec(),
                  //view创建完成时的回调
                  onPlatformViewCreated: (id) {
                    viewId = id;
                  },
                ),
              );

    更新数据

    //这里设置的标识 MethodChannel('com.flutter_to_native_test_textview_$viewId');
    // 与android MethodChannel methodChannel = new MethodChannel(messenger, "com.flutter_to_native_test_textview_" + id); 中注册的一至
    void clickUpdtae(){
    _channel = new MethodChannel('com.flutter_to_native_test_textview_$viewId');
     updateTextView();
    }

    //这里的标识 updateText
    //与android 中接收消息的方法中
    //if ("updateText".equals(methodCall.method)) {...} 一至
    void updateTextView() async {
        return _channel.invokeMethod('updateText', "更新内容");
     }

    通过onPlatformViewCreated回调,监听原始组件成功创建,并能够在回调方法的参数中拿到当前组件的id,这个id是系统随机分配的,然后通过这个分配的id加上我们的组件名称最为前缀创建一个和组件通讯的MethodChannel,拿到channel对象之后就可以通过invokeMethod方法向原生组件发送消息了,这里这里调用的是‘updateText’这个方法,参数是一个String
    ————————————————
    版权声明:本文为CSDN博主「早起的年轻人」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/zl18603543572/article/details/95983215

     

     

     

    展开全文
  • flutter调用android原生组件

    千次阅读 2019-05-07 11:31:06
    写一个小例子,比如在flutter的界面中显示android原生的TextView组件, 效果图: 步骤如下: 1、通过Android studio打开flutter工程,选中工程名,单击鼠标右键,"Flutter"->"Open Android module in ...

    写一个小例子,比如在flutter的界面中显示android原生的TextView组件,

    效果图:

    步骤如下:

    1、通过Android studio打开flutter工程,选中工程名,单击鼠标右键,"Flutter"->"Open Android module in Android Studio",打开Android模块。

    2、创建一个Class实现PlatformView接口,比如新建CustomView类,实现PlatformView接口,在CustomView的构造方法中实例化TextView,构造方法也可以接收外部传来的参数,如TextView要显示的文本text。在getView()方法中返回TextView实例.

    package com.example.eiss_app.plugin;
    
    import android.content.Context;
    import android.view.View;
    import android.widget.TextView;
    
    import io.flutter.plugin.platform.PlatformView;
    
    public class CustomView implements PlatformView {
    
        private TextView textView;
    
        public CustomView(Context context,String text) {
            textView = new TextView(context);
            textView.setText(text);
        }
    
        @Override
        public View getView() {
            return textView;
        }
    
        @Override
        public void dispose() {
    
        }
    }

    3、创建一个Class继承自PlatformViewFactory,重写create方法,在create方法中实例化刚刚的View类CustomView,然后返回。create方法的第三个参数表示flutter传递给android的参数。

    package com.example.eiss_app.plugin;
    
    import android.content.Context;
    
    import java.util.Map;
    
    import io.flutter.plugin.common.MessageCodec;
    import io.flutter.plugin.platform.PlatformView;
    import io.flutter.plugin.platform.PlatformViewFactory;
    
    public class CustomViewFactory extends PlatformViewFactory {
    
        public CustomViewFactory(MessageCodec<Object> messageCodec) {
            super(messageCodec);
        }
    
        @Override
        public PlatformView create(Context context, int i, Object o) {
            Map<String,Object> param = (Map<String,Object>)o;
            String text = (String)param.get("text");
            return new CustomView(context,text);
        }
    }
    

    4、创建一个class用来注册view,这个class提供一个方法,用来注册,方法名随便写,需要一个参数PluginRegistry,具体如下:

         注意 registrar.platformViewRegistry().registerViewFactory("widget.name", new CustomViewFactory(new StandardMessageCodec()))中的widget.name,这个会在flutter中用到。

    package com.example.eiss_app.plugin;
    
    import android.util.Log;
    
    import io.flutter.plugin.common.PluginRegistry;
    import io.flutter.plugin.common.StandardMessageCodec;
    
    public class CustomViewRegistrant {
        private static final String TAG = CustomViewRegistrant.class.getName();
    
        public static void registerWith(PluginRegistry registry) {
            final String key = TextureWidgetRegistrant.class.getCanonicalName();
            Log.i(TAG,"registerKey="+key);
            if (registry.hasPlugin(key)) {
                return;
            }
            PluginRegistry.Registrar registrar = registry.registrarFor(key);
            registrar.platformViewRegistry().registerViewFactory("widget.name", new CustomViewFactory(new StandardMessageCodec()));
        }
    }

    5、在MainActivity中调用注册类。

          注意:不用手动修改GeneratedPluginRegistrant类,自己写的插件不要放到GeneratedPluginRegistrant中注册,而是应该自己写注册类,然后在MainActivity中调用注册类

    package com.example.eiss_app;
    
    import android.os.Bundle;
    import android.util.Log;
    
    import com.example.eiss_app.plugin.hkvideo.CustomViewRegistrant;
    import com.example.eiss_app.plugin.hkvideo.HKPlayer;
    import com.example.eiss_app.plugin.hkvideo.HKVideoPlayerFlutterPlugin;
    import com.example.eiss_app.plugin.hkvideo.TextureWidgetRegistrant;
    import com.hikvision.open.hikvideoplayer.HikVideoPlayerFactory;
    
    import io.flutter.app.FlutterActivity;
    import io.flutter.plugins.GeneratedPluginRegistrant;
    
    public class MainActivity extends FlutterActivity {
    
      private static final String TAG = MainActivity.class.getName();
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GeneratedPluginRegistrant.registerWith(this);
        CustomViewRegistrant.registerWith(this);
      }
    
    
    }

    6、在flutter中使用,使用AndroidView,viewType为刚刚定义的"widget.name".

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    class My extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Center(
          child: AndroidView(
            viewType: 'widget.name',
            creationParams: {'text': 'Flutter传给Android的参数'},
            creationParamsCodec: StandardMessageCodec(),
          ),
        );
      }
    }
    

     

    展开全文
  • flutter代码 import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(MaterialApp( debugShowCheckedModeBanner: false, title: '测试...
  • 第一步:android原生代码示例 a:先创建一个类(可以将不同的功能分别放到不同的类中) class AppUtils: MethodChannel.MethodCallHandler { companion object{ //声明注册的方法 const val CHANNEL = "huang/...
  • 做过很多的混合开发项目,有一些要调用系统API的功能还是需要原生开发人员提供相关的SDK插件来实现,还有特定一些需求,比如开发个水印相机等,Android开发的插件SDK一般都是以.aar提供,那么flutter怎么和原生交互...
  • flutter端: import 'package:flutter/services.dart'; class GeocoderToAddress{ static const MethodChannel _channel = const MethodChannel('analysis_address'); static Future<String> getPlatfo...

空空如也

1 2 3 4 5 ... 19
收藏数 365
精华内容 146
关键字:

flutter调用android