这是我参与更文挑战的第25天,活动详情查看: 更文挑战html
前面咱们聊了 Flutter 中 Text 各类属性样式调配的展现效果,这篇咱们稍微深刻一点,看看 Text 的源码以及富文本的使用,最后聊聊选择文本的应用。git
查看富文本以前,咱们先看看上篇的 Text
源码,其实在上上篇咱们演示行高参数的时候就能够看到虽然咱们使用的是 Text
,可是渲染时在 Widget 树中看到的是 RichText
。github
出现上述的缘由是什么呢?咱们来瞅瞅源码吧
首先 Text
继承自 StatelessWidget
,下面咱们就直接看 build
方法便可。api
这里看到上面注释圈起来的部分,说 RichText 能够更好的让咱们控制文字样式markdown
上面👆🏻能够看出 build 方法最终返回的是 result
(550 行),而 result
建立的就是 RichText
对象,通常咱们没有给文字添加语义标签 semanticsLabel
,因此就会直接返回 RichText
Widget 了。less
如今咱们就知道为啥咱们写的是 Text ,但实际是 RichText 的 Widget 的缘由了ide
上面咱们知道了缘由,下面咱们就从一个简单的富文原本走进 RichText
吧
👆🏻上面的效果,若是单独使用 Text
写是否是咱们要外部嵌套一个 Row+3个Text
, 咱们还要考虑换行问题,这样就比较麻烦了,若是咱们使用 RichText
,就不须要考虑这么多,关心样式便可。oop
RichText(
text: TextSpan(
text: 'Flutter Widgets 已有 ',
children: [
TextSpan(
text: '25',
// 设置个性化覆盖样式
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
// 复用上层通用样式
TextSpan(text: ' 系列文章'),
],
// 设置通用样式
style: TextStyle(
color: Colors.blue,
),
),
)
复制代码
这里咱们主要关心样式的设置,有 2
个点须要注意:post
上面咱们使用到了 TextSpan
,来一块儿看看他的属性吧。ui
这里咱们看到 TextSpan
继承自 InlineSpan
,实现了 HitTestTarget
(命中检测)和 MouseTrackerAnnotation
(鼠标追踪),属性上也很是的简单,经常使用的可能就是前 4 个,而后前 3 个咱们都了解使用过了,下面来看看第四个吧。
我如今把 25 这个数字变成红色,而且要加上点击事件怎么办呢?这时候就用到了第 4 个属性 recognizer
。
// 点击手势检测器
late TapGestureRecognizer tapRecognizer;
@override
void initState() {
tapRecognizer = TapGestureRecognizer()..onTap = _handleTap;
super.initState();
}
/// 处理点击
void _handleTap() {
// 打印
print('tapRecognizer 25');
// 设置震动效果
HapticFeedback.vibrate();
}
// 这里只贴图 25 的部分代码
TextSpan(
text: '25',
// 设置个性化覆盖样式
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.red,
),
// 设置点击检测器
recognizer: tapRecognizer,
)
复制代码
这样咱们再作,好比用户协议与隐私政策的时候就能够用到啦,能够作单独的样式和跳转。
上面咱们还只是说了富文本中文字多样式的状况,还有嵌套各类图片的状况,在实际富文本应用时比这个要复杂的多,文章中示例作核心的解法,具体还须要实际应用和创新。
若是在上面的基础上咱们须要加上图标怎么处理呢?看看下面的代码
RichText(
text: TextSpan(
children: [
// Flutter Logo
WidgetSpan(child: FlutterLogo()),
TextSpan(text: 'Flutter Widgets 已有 '),
TextSpan(
text: '25',
// 设置个性化覆盖样式
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.red,
),
recognizer: tapRecognizer,
),
// 连接图标
WidgetSpan(
child: Icon(
Icons.link,
size: 16,
color: Colors.blue,
),
),
// 复用上层通用样式
TextSpan(text: ' 系列文章'),
// 复制图标
WidgetSpan(
child: Icon(
Icons.copy,
size: 16,
color: Colors.grey,
),
),
],
// 设置通用样式
style: TextStyle(
color: Colors.blue,
),
),
)
复制代码
这里只是演示,实际项目中会根据下发的文本协议来解析,而后生成对应的 Widget 组合
另一种建立富文本的方式就是使用 Text.rich
,下面来一块儿看看代码吧
Text.rich(
TextSpan(
children: [
WidgetSpan(child: FlutterLogo()),
TextSpan(text: 'Flutter Widgets 已有 '),
TextSpan(
text: '25',
// 设置个性化覆盖样式
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.red,
),
recognizer: tapRecognizer,
),
WidgetSpan(
child: Icon(
Icons.link,
size: 16,
color: Colors.blue,
),
),
// 复用上层通用样式
TextSpan(text: ' 系列文章'),
WidgetSpan(
child: Icon(
Icons.copy,
size: 16,
color: Colors.grey,
),
),
],
// 设置通用样式
style: TextStyle(
color: Colors.blue,
),
),
)
复制代码
到这里 RichText
基本就聊完了,基础的样式咱们在前 2 篇文章已经聊过,能够在专栏中回看。
上面展现的文本都是没法选择复制的,在实际项目中,有些内容文字是须要支持用户能够选择复制的,这时咱们就须要将 Text
改变成 SelectableText
SelectableText(
"Text - ZeroFlutter",
style: TextStyle(
// 颜色蓝色
color: Colors.blue,
// 字号 24
fontSize: 24,
),
)
复制代码
在实际使用时,你会发现没法指定溢出样式了,默认就是直接剪裁掉了。
由于考虑到,复制确定是对全部文本进行操做,若是咱们溢出样式是... 那么复制出来就是展现的样式,确定不符合需求。
因此在实际项目中,若是是长按复制所有可使用 Text
,选择复制能够 SelectableText
。
与 Text.rich
一致,要使用富文本时,能够直接使用 SelectableText.rich
。
可是这里有个显示就是咱们不能使用
WidgetSpan
了,只能使用TextSpan
SelectableText.rich(
TextSpan(
children: [
// WidgetSpan(child: FlutterLogo()),
TextSpan(text: 'Flutter Widgets 已有 '),
TextSpan(
text: '25',
// 设置个性化覆盖样式
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.red,
),
recognizer: tapRecognizer,
),
// WidgetSpan(
// child: Icon(
// Icons.link,
// size: 16,
// color: Colors.blue,
// ),
// ),
// 复用上层通用样式
TextSpan(text: ' 系列文章'),
// WidgetSpan(
// child: Icon(
// Icons.copy,
// size: 16,
// color: Colors.grey,
// ),
// ),
],
// 设置通用样式
style: TextStyle(
color: Colors.blue,
),
),
)
复制代码
基于 Flutter 🔥 最新版本
👏 欢迎点赞➕收藏➕关注,有任何问题随时在下面👇评论,我会第一时间回复哦