描述
在开发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,为传给原生的数据
}
- Color fillColor; 这里颜色定义为Color类型,是为了让flutter层使用无感
- 'fillColor':fillColor.value.toRadixString(16),这里是传给原生的color,Color类型通过fillColor.value.toRadixString(16)转为string类型,实际传给原生是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];
网友评论