了解 Unicode 在 Flutter 上的展示

2019-11-02  本文已影响0人  前行的乌龟
image

以前我对 emoji 是一头雾水,尤其是接入微信登录时,对于名字带表情的都是简单过滤处理,很暴力不是,我也试了好几次像支持 emoji,单奈何就是不行,今天看到了有关文章,总结了下,总算是清楚了,去了我一块心病,对于 emoji 不清楚的同学可以试试看,也许对你有帮助

emoji 其实就是 Unicode 16进制编码~


Unicode 简介

Unicode 编码是国际最通用的字符编码了,Unicode 里给不同语言的每个字符,其他各种符号,包括 emoji 表情都设置有自己独立的编号,所以就不会再出现乱的问题了,但是随着各种符号越来越多,尤其是 emoji 表情大行其道之后,这符号的数量与日俱增,为了装的下这么多符号,目前 Unicode 最多已经采用到 32位来存储了

UTF 有好几种,不是说只用最大编码的,不同的系统根据实际需求会选择自己默认支持的 UTF,一般文字的话 UTF-8 就足够了,但是处理 emoji 就得 UTF-32 了,具体在于使用场景


Unicode 储存图

UTF-32 储存值从 U+0000U+10FFFF,分成14个扇区存储,每一个扇区有 256 个小块,每个小块有 16×16 = 256 个编码点,总体下来每个扇区有 65536 个 编码点

扇区图:没一个大块就是一个扇区


image

不同语言的字符,包括古今文字,上古语言,符号,emoji 都存储在不同的扇区内

Unicode 所有的字符可以在官方网站上查询到:

所以这 Unicode 数值也挺乱的,大家要注意,对于不同的数值范围 Dart 中有不同的保存格式:


Flutter 上显示 emoji

Flutter 上想要正确显示 emoji 表情,请示就是给不同数值范围的 Unicode 编码套整个的格式

显示单个 emoji

var index = "\u{1f44f}";
image

显示多个,带文字混排

Runes input = new Runes(
  '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d} 哇哈哈哈哈!!!');
var index = String.fromCharCodes(input);
image

Dart 字符编码的 API

Dart 上又一个接受 UTF-32 编码的类:Runes,可以把 UTF-32 处理成能是别的 10进制数据

Dart 文字显示默认是 UTF-16 的,我们兼容 emoji 的话最好用 UTF-32,必须用 Runes 这个类,Runes 可以让我们按照 UTF-32 存储展示字符

dart:core 库提供了获取字符编码的 API:

var index1 = "我";
var index2 = "我是富翁,我老有钱了";

print("index1:${index1.codeUnitAt(0)}");
print("index1:${index2.codeUnits}");
print("index1:${index1.runes}");
I/flutter ( 6849): index1:25105
I/flutter ( 6849): index1:[25105, 26159, 23500, 32705, 65292, 25105, 32769, 26377, 38065, 20102]
I/flutter ( 6849): index1:(25105)

我详细解释下,有点绕,不容易搞清楚


例子:

Unicode 编码都是 16 进制的,通常表示为 \uXXXX,其中这个 xxxx 就是具体的 16进制值

比如这个符号:他的 16进制 Unicode 编码是 \u2665,2665 的 10 进制 = 9829

image

我们来看下:

Runes input = new Runes('\u2665');
var index = String.fromCharCodes(input);
print("index1:${index.codeUnitAt(0)}");
print("index1:${index.codeUnits}");
print("index1:${index.runes}");
I/flutter ( 6849): index1:9829
I/flutter ( 6849): index1:[9829]
I/flutter ( 6849): index1:(9829)

拿到的结果正好对的上 10进制数值,我们转成 16进制加上 \u 就是 Unicode 编码了

Runes input = new Runes('\u2665');
var index = String.fromCharCodes(input);
var index = String.fromCharCode(9829);
上一篇下一篇

猜你喜欢

热点阅读