样式文本
简介
StyledText 是一个用于显示富文本的组件,支持混合样式、点击回调和指针事件。它渲染为一个包含多个 TextSpan 子项的 RichText 组件,让你可以精细控制文本的每个片段。
StyledText 支持两种模式:
- 子组件模式 -- 传入一个
Text组件列表,每个组件有自己的样式 - 模板模式 -- 在字符串中使用
{{placeholder}}语法,将占位符映射到样式和操作
基本用法
// Children mode - list of Text widgets
StyledText(
children: [
Text("Hello ", style: TextStyle(color: Colors.black)),
Text("World", style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold)),
],
)
// Template mode - placeholder syntax
StyledText.template(
"Welcome to {{Nylo}}!",
styles: {
"Nylo": TextStyle(fontWeight: FontWeight.bold, color: Colors.blue),
},
)
子组件模式
传入 Text 组件列表来组合样式文本:
StyledText(
style: TextStyle(fontSize: 16, color: Colors.black),
children: [
Text("Your order "),
Text("#1234", style: TextStyle(fontWeight: FontWeight.bold)),
Text(" has been "),
Text("confirmed", style: TextStyle(color: Colors.green, fontWeight: FontWeight.bold)),
Text("."),
],
)
基础 style 会应用于没有自定义样式的子组件。
指针事件
检测指针进入或离开文本片段:
StyledText(
onEnter: (Text text, PointerEnterEvent event) {
print("Hovering over: ${text.data}");
},
onExit: (Text text, PointerExitEvent event) {
print("Left: ${text.data}");
},
children: [
Text("Hover me", style: TextStyle(color: Colors.blue)),
Text(" or "),
Text("me", style: TextStyle(color: Colors.red)),
],
)
模板模式
使用 StyledText.template() 配合 {{placeholder}} 语法:
StyledText.template(
"By continuing, you agree to our {{Terms of Service}} and {{Privacy Policy}}.",
style: TextStyle(color: Colors.grey),
styles: {
"Terms of Service": TextStyle(color: Colors.blue, decoration: TextDecoration.underline),
"Privacy Policy": TextStyle(color: Colors.blue, decoration: TextDecoration.underline),
},
onTap: {
"Terms of Service": () => routeTo("/terms"),
"Privacy Policy": () => routeTo("/privacy"),
},
)
{{ }} 之间的文本既是显示文本,也是用于查找样式和点击回调的键。
样式占位符
将占位符名称映射到 TextStyle 对象:
StyledText.template(
"Framework Version: @{{$version}}",
style: textTheme.bodyMedium,
styles: {
version: TextStyle(fontWeight: FontWeight.bold),
},
)
点击回调
将占位符名称映射到点击处理函数:
StyledText.template(
"{{Sign up}} or {{Log in}} to continue.",
onTap: {
"Sign up": () => routeTo(SignUpPage.path),
"Log in": () => routeTo(LoginPage.path),
},
styles: {
"Sign up": TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
"Log in": TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
},
)
管道分隔键
使用管道符 | 分隔键,将相同的样式或回调应用于多个占位符:
StyledText.template(
"Available in {{English}}, {{French}}, and {{German}}.",
styles: {
"English|French|German": TextStyle(
fontWeight: FontWeight.bold,
color: Colors.blue,
),
},
onTap: {
"English|French|German": () => showLanguagePicker(),
},
)
这会将相同的样式和回调映射到所有三个占位符。
参数
StyledText(子组件模式)
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
children |
List<Text> |
必填 | Text 组件列表 |
style |
TextStyle? |
null | 所有子组件的基础样式 |
onEnter |
Function(Text, PointerEnterEvent)? |
null | 指针进入回调 |
onExit |
Function(Text, PointerExitEvent)? |
null | 指针离开回调 |
spellOut |
bool? |
null | 逐字符拼写文本 |
softWrap |
bool |
true |
启用软换行 |
textAlign |
TextAlign |
TextAlign.start |
文本对齐方式 |
textDirection |
TextDirection? |
null | 文本方向 |
maxLines |
int? |
null | 最大行数 |
overflow |
TextOverflow |
TextOverflow.clip |
溢出行为 |
locale |
Locale? |
null | 文本语言环境 |
strutStyle |
StrutStyle? |
null | 支撑样式 |
textScaler |
TextScaler? |
null | 文本缩放器 |
selectionColor |
Color? |
null | 选中高亮颜色 |
StyledText.template(模板模式)
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
text |
String |
必填 | 使用 {{placeholder}} 语法的模板文本 |
styles |
Map<String, TextStyle>? |
null | 占位符名称到样式的映射 |
onTap |
Map<String, VoidCallback>? |
null | 占位符名称到点击回调的映射 |
style |
TextStyle? |
null | 非占位符文本的基础样式 |
所有其他参数(softWrap、textAlign、maxLines 等)与子组件构造函数相同。
文本扩展
Nylo Website 为 Flutter 的 Text 组件扩展了排版和实用方法。
排版样式
将 Material Design 排版样式应用于任何 Text 组件:
Text("Hello").displayLarge()
Text("Hello").displayMedium()
Text("Hello").displaySmall()
Text("Hello").headingLarge()
Text("Hello").headingMedium()
Text("Hello").headingSmall()
Text("Hello").titleLarge()
Text("Hello").titleMedium()
Text("Hello").titleSmall()
Text("Hello").bodyLarge()
Text("Hello").bodyMedium()
Text("Hello").bodySmall()
Text("Hello").labelLarge()
Text("Hello").labelMedium()
Text("Hello").labelSmall()
每个方法都接受可选的覆盖参数:
Text("Welcome").headingLarge(
color: Colors.blue,
fontWeight: FontWeight.w700,
letterSpacing: 1.2,
)
可用的覆盖参数(所有排版方法通用):
| 参数 | 类型 | 描述 |
|---|---|---|
color |
Color? |
文本颜色 |
fontSize |
double? |
字体大小 |
fontWeight |
FontWeight? |
字体粗细 |
fontStyle |
FontStyle? |
斜体/正常 |
letterSpacing |
double? |
字母间距 |
wordSpacing |
double? |
单词间距 |
height |
double? |
行高 |
decoration |
TextDecoration? |
文本装饰 |
decorationColor |
Color? |
装饰颜色 |
decorationStyle |
TextDecorationStyle? |
装饰样式 |
decorationThickness |
double? |
装饰粗细 |
fontFamily |
String? |
字体系列 |
shadows |
List<Shadow>? |
文本阴影 |
overflow |
TextOverflow? |
溢出行为 |
实用方法
// Font weight
Text("Bold text").fontWeightBold()
Text("Light text").fontWeightLight()
// Alignment
Text("Left aligned").alignLeft()
Text("Center aligned").alignCenter()
Text("Right aligned").alignRight()
// Max lines
Text("Long text...").setMaxLines(2)
// Font family
Text("Custom font").setFontFamily("Roboto")
// Font size
Text("Big text").setFontSize(24)
// Custom style
Text("Styled").setStyle(TextStyle(color: Colors.red))
// Padding
Text("Padded").paddingOnly(left: 8, top: 4, right: 8, bottom: 4)
// Copy with modifications
Text("Original").copyWith(
textAlign: TextAlign.center,
maxLines: 2,
style: TextStyle(fontSize: 18),
)
示例
条款和条件链接
StyledText.template(
"By signing up, you agree to our {{Terms}} and {{Privacy Policy}}.",
style: TextStyle(color: Colors.grey.shade600, fontSize: 14),
styles: {
"Terms|Privacy Policy": TextStyle(
color: Colors.blue,
decoration: TextDecoration.underline,
),
},
onTap: {
"Terms": () => routeTo("/terms"),
"Privacy Policy": () => routeTo("/privacy"),
},
)
版本显示
StyledText.template(
"Framework Version: {{$nyloVersion}}",
style: textTheme.bodyMedium!.copyWith(
color: NyColor(
light: Colors.grey.shade800,
dark: Colors.grey.shade200,
).toColor(context),
),
styles: {
nyloVersion: TextStyle(fontWeight: FontWeight.bold),
},
)
混合样式段落
StyledText(
style: TextStyle(fontSize: 16, height: 1.5),
children: [
Text("Flutter "),
Text("makes it easy", style: TextStyle(fontWeight: FontWeight.bold)),
Text(" to build beautiful apps. With "),
Text("Nylo", style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold)),
Text(", it's even faster."),
],
)
排版链式调用
Text("Welcome Back")
.headingLarge(color: Colors.black)
.alignCenter()