Flutter如何插件开发、自定义字体、国际化

一、前言 今天学习插件开发, Flutter 使用一个灵活的系统,允许调用特定平台(iOS/Android)的API,无论在 Android 上的 Java 或者 Kotlin 代码中,还是 iOS 上的 Object-C 或者 Swift 代码中均可使用。 Flutter 平台特定的 API 支持不依赖于代码生成,而是依...

 

一、前言

今天学习插件开发,Flutter使用一个灵活的系统,允许调用特定平台(iOS/Android)的API,无论在Android上的Java或者Kotlin代码中,还是iOS上的Object-C或者Swift代码中均可使用。Flutter平台特定的API支持不依赖于代码生成,而是依赖于灵活的消息传递方式:

  • 应用的Flutter部分通过平台通道(platform channel)将消息发送到应用程序得所在宿主(iOS或Android)。
  • 宿主监听的平台通道,并接受该消息,然后它会调用特定于该平台的API(使用原生编程语言)-并响应发送客户端(即应用程序的Flutter部分)。

二、插件实例

1.插件的基本原理

要使用和创建一个Flutter插件,得要首先知道平台通道在客户端(Flutter UI)和宿主(平台)之间传递消息,用官方的图,下图:

 

平台插件基本原理

 

上面就是平台通道的结构大致描述,使用MethodChannelFlutter客户端主机(iOS/Android)之间传递消息,消息和响应都是异步传递的,这样确保用户界面(UI)保持响应,在Flutter客户端,Flutter通过MethodChannel类发送与方法调用相对应的消息。在平台上,Android上通过MethodChannel类接收方法调用并发送结果,iOS上则可以通过FlutterMethodChannel类接收方法调用并发送结果。这些类允许开发者开发一个平台插件,在上图可以发现,箭头是双向的,也就是方法调用也可以朝反方向发送,简而言之:可以从Flutter调用Android/iOS的代码,也可以从Android/iOS调用Flutter。标准平台通道使用的是标准消息解码器,支持简单高效的将JSON格式的值二进制序列化,如布尔值、数字、字符串、字节缓冲区以及这些数据的列表和映射,发送和接收值会自动对这些值进行序列化和反序列化,下面表格列出展示平台端如何接收Dart,反过来也是一样。

 

DartAndroidiOS
nullnullnil(NSNull when nested)
booljava.lang.BooleanNSNumber numberWithBool:
intjava.lang.IntegerNSNumber numberWithInt:
int, if 32 bits not enoughjava.lang.LongNSNumber numberWithLong:
int, if 64 bits not enoughjava.math.BigIntegerFlutterStandardBigInteger
doublejava.lang.DoubleNSNumber numberWithDouble:
Stringjava.lang.StringNSString
Uint8Listbyte[]FlutterStandardTypedData typedDataWithBytes:
Int32Listint[]FlutterStandardTypedData typedDataWithInt32:
Int64Listlong[]FlutterStandardTypedData typedDataWithInt64:
Float64Listdouble[]FlutterStandardTypedData typedDataWithFloat64:
Listjava.util.ArrayListNSArray
Mapjava.util.HashMapNSDictionary
   

2.简单例子1-返回数值

了解原理,下面简单实现平台和客户端传递数据的Flutter平台插件。

2.1.Flutter平台客户端

首先,需要创建Flutter平台客户端,构建通道,使用具有基本传递数据功能的单平台方法MethodChannel通道的客户端和宿主通过通道构造函数中传递的通道名称进行连接,单个应用中使用的所有通道名称必须是唯一的,官方建议是通道名称前加一个唯一的“域名前缀”,例如samoles.flutter.io/battery

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

class _PluginTestState extends State<PluginTest> {
  //创建通道名称 必须唯一
  static const platform = const MethodChannel('sample.flutter.io/data');
}
复制代码

下面在MethodChannel上调用一个方法,指定通过String标识符data调用的具体方法。如果当前平台不支持API那么调用会失败,因此需要将invokeMethod调用包含在try-catch语句中,返回的数值来更新_data:

class _PluginTestState extends State<PluginTest> {
  //创建通道名称 必须唯一
  static const platform = const MethodChannel('sample.flutter.io/data');
  String _data;

  Future<Null> _returndata() async{
    String data;
    try{
      //1.invokeMethod('xxxx') xxx可以自己命名
      final int resultData = await platform.invokeMethod('data');
      data = "平台返回数值:$resultData";
    }catch(e){
      data = "错误:${e.message}";
    }
    
    //状态更新
    setState(() {
      _data = data;
    });

  }
}
复制代码

主界面添加一个返回数值的文本,和一个浮动按钮:

class _PluginTestState extends State<PluginTest> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      //appBar
      appBar: AppBar(
        title: Text("插件例子"),
        //标题居中
        centerTitle: true,
      ),
      body:new Center(
        child: Text("$_data"),
      ),
      floatingActionButton : FloatingActionButton(
          onPressed: _returndata,
          tooltip: "获取平台返回的值",
          child: new Icon(Icons.audiotrack)
      ),

    );
  }

}
复制代码

2.2.使用Java添加Android平台特定的实现

首先在Android Studio打开Flutter应用的Android部分:

  1. Android Studio 选择File > Open
  2. 定位到自己的项目根目录,然后选择里面的android文件夹,点击OK 如下:

 

打开android目录

 

3. 在java目录下打开MainActivity.java,我打开项目编译报错,没管。 下面,在onCreate里创建MethodChannel并设置一个MethodCallHandler。确保使用在Flutter客户端使用的通道名称相同:

 

public class MainActivity extends FlutterActivity {
  
  //1.通道名称
  private static final String CHANNEL = "sample.flutter.io/data";
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //2.创建MethodChannel 并且设置MethodCallHandler
    new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(new MethodChannel.MethodCallHandler(){
      @Override
      public void onMethodCall(MethodCall call, MethodChannel.Result result){
        
      }
    });
    
    GeneratedPluginRegistrant.registerWith(this);
  }
}
复制代码

编写Java代码,用于调用Android上的随机函数,和在Android项目上编写代码完全一样,在MainActivity方法添加下面方法:

  //返回特定的数值
  private int getData() {
    return 7;
  }
复制代码

最后,在完成之前添加的onMethodCall方法后,还需要处理一个平台方法data,所以需要在call参数中测试它,这个方法里面的逻辑只是调用getData这个方法,并使用response参数返回成功和错误情况的响应,如果调用未知的方法,会报告错误信息:

    new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
      @Override
      public void onMethodCall(MethodCall call, MethodChannel.Result result) {
        //3.处理一个平台方法data 和在平台上invokeMethod(xxxx)对应
        if (call.method.equals("data")) {
          int data = getData();
          result.success(data);
        } else {
          result.notImplemented();
        }
      }
    });

复制代码

现在就可以运行这应用程序,点击按钮,就能获取Android主机返回的数值7,效果图如下:

 

主机返回的数据

 

查看更多详细内容

flutter学习插件开发和国际化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值