美文网首页
了解 Unicode 在 Flutter 上的展示

了解 Unicode 在 Flutter 上的展示

作者: 前行的乌龟 | 来源:发表于2019-11-02 00:50 被阅读0次
image

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

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


Unicode 简介

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

  • UTF-8 - 占用一到四个字节,主要用来存储英文系字符
  • UTF-16 - 占用二或四个字节,主要存储世界上所有文字
  • UTF-32 - 占用四个字节,主要方 emoji 表情这种

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


Unicode 储存图

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

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


image

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

  • Unicode 0 号平面(0000-FFFF)
  • Unicode 1 号平面(10000-1FFFF)

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

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

  • \u2665 - 4个16进制的数的这么写
  • \u{1f600} - 但要不是4位的就得在数值前加{}

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:

  • String.codeUnitAt(index) - 返回指定字符的 10 进制 Unicode 索引
  • String.codeUnits - 返回所有字符的 10 进制 Unicode 索引,结果是个集合
  • String.runes - 返回所有字符的 10 进制 Unicode 编码值,结果是个集合
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 编码了

  • 16 进制 Unicode 编码显示,使用 Runes 类包裹数据
Runes input = new Runes('\u2665');
var index = String.fromCharCodes(input);
  • 10 进制 就不用 Runes 了,直接走
var index = String.fromCharCode(9829);

相关文章

网友评论

      本文标题:了解 Unicode 在 Flutter 上的展示

      本文链接:https://www.haomeiwen.com/subject/ixccbctx.html