描述
在開發(fā)flutter地圖插件時蕊苗,其中有一個功能是要實現(xiàn)顯示簽到地點范圍栗精,簽到地點范圍是一個圓圈益老,為了通用彪蓬,需要從flutter層傳圓圈的填充顏色給原生,記錄下flutter和原生顏色的傳輸捺萌。
題外話
flutter和原生數(shù)據(jù)的傳輸档冬,個人比較喜歡的方式就是,把傳輸?shù)臄?shù)據(jù)都轉(zhuǎn)成string類型桃纯,并且是json 格式string類型來傳輸酷誓,不管是model還是單個數(shù)據(jù),這樣我們可以像解析網(wǎng)絡(luò)請求返回的數(shù)據(jù)一樣解析flutter和原生傳輸?shù)臄?shù)據(jù)态坦。
之前做flutter和原生通訊的插件盐数,試過直接把單個數(shù)據(jù)如int類型直接從flutter層傳給原生,但后面flutter sdk升級后伞梯,導(dǎo)致通訊失敗玫氢,花費了一些時間排查解決,所以flutter和原生數(shù)據(jù)的傳輸用json 格式string類型來傳輸靠譜又便于擴展谜诫;
踩過坑
最開始做法是:flutter層顏色定義為int型漾峡,原生android也用int型接收,android端會報錯猜绣,如下
com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: Expected an int but was 4294967295
上面?zhèn)鞯念伾禐?xffffffff,對應(yīng)的10進(jìn)制值為4294967295灰殴,對int會越界;但如果直接用0xffffffff在原生android設(shè)置顏色掰邢,它的參數(shù)也為int型牺陶,不會報錯,并且正常顯示辣之,翻譯就是setTextColor(0xffffffff)正常顯示顏色掰伸,setTextColor(4294967295)直接報錯;
仔細(xì)看設(shè)置顏色的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 )狮鸭,如果作用在整型數(shù)組上說明數(shù)組中的每一個值都代表一個顏色值
進(jìn)入正題
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轉(zhuǎn)為json格式string赌髓,為傳給原生的數(shù)據(jù)
}
- Color fillColor; 這里顏色定義為Color類型,是為了讓flutter層使用無感
- 'fillColor':fillColor.value.toRadixString(16),這里是傳給原生的color催跪,Color類型通過fillColor.value.toRadixString(16)轉(zhuǎn)為string類型锁蠕,實際傳給原生是string類型,比如白色懊蒸,原生接收到的值為ffffffff的字符串荣倾,這樣在ios和android都通用;
- String toJsonString() => jsonEncode(toJson()); 將model轉(zhuǎn)為json格式string骑丸,為傳給原生的數(shù)據(jù)
2舌仍、flutter使用
///flutter層使用
MarkerCircleOptions markOptions = MarkerCircleOptions(
...
fillColor: Color(0x263F8EF5),//flutter層使用顏色無感
...
);
_aMapController.addCircleMarker(markOptions);
///flutter傳原生方法
Future addCircleMarker(MarkerCircleOptions options) {
final _optionsJson = options.toJsonString();//將model轉(zhuǎn)為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];
}
// 從六位數(shù)值中找到RGB對應(yīng)的位數(shù)并轉(zhuǎn)換
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];