Flutter

插件化开发之flutter和原生颜色传输

2020-11-19  本文已影响0人  HawkFlying

描述

在开发flutter地图插件时,其中有一个功能是要实现显示签到地点范围,签到地点范围是一个圆圈,为了通用,需要从flutter层传圆圈的填充颜色给原生,记录下flutter和原生颜色的传输。

题外话

flutter和原生数据的传输,个人比较喜欢的方式就是,把传输的数据都转成string类型,并且是json 格式string类型来传输,不管是model还是单个数据,这样我们可以像解析网络请求返回的数据一样解析flutter和原生传输的数据。
之前做flutter和原生通讯的插件,试过直接把单个数据如int类型直接从flutter层传给原生,但后面flutter sdk升级后,导致通讯失败,花费了一些时间排查解决,所以flutter和原生数据的传输用json 格式string类型来传输靠谱又便于扩展;

踩过坑

最开始做法是:flutter层颜色定义为int型,原生android也用int型接收,android端会报错,如下

com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: Expected an int but was 4294967295 

上面传的颜色值为0xffffffff,对应的10进制值为4294967295,对int会越界;但如果直接用0xffffffff在原生android设置颜色,它的参数也为int型,不会报错,并且正常显示,翻译就是setTextColor(0xffffffff)正常显示颜色,setTextColor(4294967295)直接报错;
仔细看设置颜色的int型前面多个@ColorInt注解,估计是@ColorInt的作用:

public abstract void setTextColor(@ColorInt int color);

@ColorInt
Denotes that the annotated element represents a packed color int, AARRGGBB. If applied to an int array, every element in the array represents a color integer.
翻译:被ColorInt注解的元素是一个包装之后的颜色整型值 ( 格式:AARRGGBB ),如果作用在整型数组上说明数组中的每一个值都代表一个颜色值

进入正题

flutter层
1、定义flutter传给原生的model
import 'dart:convert';
import 'dart:ui';

class MarkerCircleOptions {
  ...
  ///圆圈填充颜色
  Color fillColor;//这里颜色定义为Color类型,是为了让flutter层使用无感
 

  MarkerCircleOptions({
     ...
    @required this.fillColor,
     ...
  });



  Map<String, Object> toJson() {
    return {
      ...
      'fillColor':fillColor.value.toRadixString(16),//实际传给原生是string类型,比如白色,原生接收到的值为ffffffff的字符串,这样在ios和android都可以处理;
    };
  }

  String toJsonString() => jsonEncode(toJson());//将model转为json格式string,为传给原生的数据


}

2、flutter使用
///flutter层使用
 MarkerCircleOptions markOptions = MarkerCircleOptions(
      ...
     fillColor: Color(0x263F8EF5),//flutter层使用颜色无感
     ...
  );
 _aMapController.addCircleMarker(markOptions);
  ///flutter传原生方法
  Future addCircleMarker(MarkerCircleOptions options) {
    final _optionsJson = options.toJsonString();//将model转为json格式string,传给原生
    return _mapChannel.invokeMethod(
      AMapNativeChannelConstant.METHOD_ADD_CIRCLE_MARKER,
      {AMapNativeParamsKeyConstant.MARKER_CIRCLE_OPTIONS: _optionsJson},
    );
  }
原生层
android

通过Color.parseColor("#"+fillColor)使用

ios

String扩展方法:

#import <Foundation/Foundation.h>

@interface NSString (Color)

- (UIColor *)hexStringToColor;

@end



#import "NSString+Color.h"


@implementation NSString (Color)

- (UIColor *)hexStringToColor {
    NSString *cString = [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];

    // String should be 6 or 8 characters
    if ([cString length] < 6) {
        return [UIColor clearColor];
    }

    // 从六位数值中找到RGB对应的位数并转换
    NSRange range;
    range.location = 0;
    range.length = 2;

    //A, R,G, B
    NSString *aString = [cString substringWithRange:range];

    range.location = 2;
    NSString *rString = [cString substringWithRange:range];

    range.location = 4;
    NSString *gString = [cString substringWithRange:range];

    range.location = 6;
    NSString *bString = [cString substringWithRange:range];

    // Scan values
    unsigned int a, r, g, b;
    [[NSScanner scannerWithString:aString] scanHexInt:&a];
    [[NSScanner scannerWithString:rString] scanHexInt:&r];
    [[NSScanner scannerWithString:gString] scanHexInt:&g];
    [[NSScanner scannerWithString:bString] scanHexInt:&b];

    return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:((float) a / 255.0f)];
}

@end

使用

UIColor xxx = [fillColor hexStringToColor];
上一篇 下一篇

猜你喜欢

热点阅读