RichText 是绘制文本的核心 widget,Text 只是 RichText 的包装而已。文本这块还是相当复杂的,本文介绍一些基本的用法。
参数解析
text
text 是一个 InlineSpan,InlineSpan 又可以嵌套 InlineSpan。每一段都可以有自己的样式。
textAlign
textAlign 负责 text 的对齐。RichText size 大于文本的 size 时有效。
wrap
wrap 默认为 true,文本自动换行,如果为 false,不会换行,只在一行显示。
overflow
overflow 默认为 TextOverflow.clip,会截断超出的文本。为 TextOverflow.ellipsis 时,按 maxLine 指定的行数显示,如果有超出显示 ...。
textScaleFactor
放大字体的因子。
maxLines
最多显示行数
selectionColor and selectionRegistrar
选择文本相关
textHeightBehavior
要会用这个参数,先要明白 什么是 leading
leading 的计算方法TextStyle.height * TextStyle.fontSize - TextStyle.fontSize
. 如果 TextStyle.height
没有设置, leading 的默认值由字体决定。一般来说 ,leading 默认不为 0,这也是为什么 文字占据的高度比字体值大的原因。height=1
可以让 leading 为 0。
如果 height 大于1,leading 会大于0,如何分配 leading 就由 textHeightBehavior 决定。
使用举例
RichText( text: TextSpan( text: 'IAM17', style: TextStyle(color: Colors.black), children: [ TextSpan( recognizer: TapGestureRecognizer() ..onTap = () { print('click flutter'); }, text: 'Flutter', style: TextStyle(fontSize: 20, color: Colors.green)), TextSpan(text: '天天更新') ])) 复制代码
这样看起来有点乱,嵌套了两层。一个文本在第一层,二个文本在第二层。如果有多个 textSpan 可以省掉第一层的文本。
RichText( text:TextSpan(style: TextStyle(color: Colors.black), children: [ TextSpan(text: 'IAM17'), TextSpan( recognizer: LongPressGestureRecognizer() ..onLongPress = () { print('click flutter'); }, text: 'Flutter', style: TextStyle(fontSize: 20, color: Colors.green)), TextSpan(text: '天天更新') ])) 复制代码
最外层的 style 是可以保留的,做为公共样式。最外层的文本去掉,这样就可以让所有文本在一个层级上,看起来更规整,也好维护。
你可能注意到本例中直接 new TapGestureRecognizer 对象,这样会导致资源不能及时释放。要释放资源,需要调用 TapGestureRecognizer 的 dispose 方法,垃圾回收不会自动执行 dispose 方法,所以需要我们手动释放。
推荐的做法是这样的。
late LongPressGestureRecognizer _longPressRecognizer; @override void initState() { super.initState(); _longPressRecognizer = LongPressGestureRecognizer() ..onLongPress = _handlePress; } @override void dispose() { _longPressRecognizer.dispose(); super.dispose(); } void _handlePress() { print('handle long ress'); } @override Widget build(BuildContext context){ return RichText( text:TextSpan(style: TextStyle(color: Colors.black), children: [ TextSpan(text: 'IAM17'), TextSpan( recognizer: _longPressRecognizer, text: 'Flutter', style: TextStyle(fontSize: 20, color: Colors.green)), TextSpan(text: '天天更新') ])) } 复制代码
不要怕麻烦,这样做肯定是没有问题的。
大多时候,一段的文本的样式都是一样的,所以 Flutter 为了我们提供了 Text,Text 把 RichText 进行了包装
return RichText( ... text: TextSpan( style: effectiveTextStyle, text: data, children: textSpan != null ? <InlineSpan>[textSpan!] : null, ), ); 复制代码
当只有一种样式的文本时,可以这样写
Text('IAM17') 复制代码
代码简化了好多。
如果有多种样式的文本,可以用 Text.rich
Text.rich( TextSpan( style: TextStyle(color: Colors.black), children: [ TextSpan(text: 'IAM17'), TextSpan(text: 'Flutter'), ])) 复制代码
所以我们一般不需要直接使用 RichText,用 Text 或 Text.rich 即可。