Text参数属性

Text用于显示简单样式文本,它包含一些控制文本显示样式的一些属性,一个简单的例子如下:
image.png

  1. Text("Hello world",
  2. textAlign: TextAlign.left,
  3. );
  4. Text("Hello world! I'm Jack. " * 4,
  5. maxLines: 1,
  6. overflow: TextOverflow.ellipsis,
  7. );
  8. Text("Hello world",
  9. textScaleFactor: 1.5,
  10. );

image.png

  1. (new) Text Text(String data,
  2. {Key key,
  3. TextStyle style,
  4. StrutStyle strutStyle,
  5. TextAlign textAlign,
  6. TextDirection textDirection,
  7. Locale locale,
  8. bool softWrap,
  9. TextOverflow overflow,
  10. double textScaleFactor,
  11. int maxLines,
  12. String semanticsLabel,
  13. TextWidthBasis textWidthBasis})

textAlign 文本的对齐方式,注意,对齐的参考系是Text widget本身。

  • TextAlign.center 居中对齐
  • TextAlign.end 结尾对齐
  • TextAlign.justify 拉伸以软换行符结尾的文本行,以填充容器的宽度
  • TextAlign.left 左对齐
  • TextAlign.right 右对齐
  • TextAlign.start 开头对齐

本例中虽然是指定了居中对齐,但因为Text文本内容宽度不足一行,Text的宽度和文本内容长度相等,那么这时指定对齐方式是没有意义的,只有Text宽度大于文本内容长度时指定此属性才有意义。下面我们指定一个较长的字符串:

  1. //字符串内容超过一行,Text宽度等于屏幕宽度,第二行文本便会居中显示
  2. Text("Hello world " * 6, //字符串重复六次
  3. textAlign: TextAlign.center,
  4. );
  5. //运行效果 Hello world Hello world Hello world Hello world Hello world Hello world
  • maxLines 指定文本显示的最大行数,默认情况下,文本是自动折行的,如果指定此参数,则文本最多不会超过指定的行。
  • overflow 如果有多余的文本,可以通过overflow来指定截断方式,默认是直接截断,本例中指定的截断方式TextOverflow.ellipsis,它会将多余文本截断后以省略符“…”表示;TextOverflow的其它截断方式请参考SDK文档。
  • textScaleFactor 代表文本相对于当前字体大小的缩放因子,相对于去设置文本的样式style属性的fontSize,它是调整字体大小的一个快捷方式。该属性的默认值可以通过 MediaQueryData.textScaleFactor 获得,如果没有MediaQuery,那么会默认值将为1.0。
  • textDirection 文字的方向
    • 这决定了如何解释[textAlign.start]和[textAlign.end]等[textAlign]值。
    • 这也用于消除如何呈现双向文本的歧义。例如,如果[data]是英文短语,后跟希伯来语短语,则在[TextDirection.ltr]上下文中,英文短语位于左侧,希伯来语短语位于右侧;而在[TextDirection.rtl]上下文中,英文短语位于右侧,希伯来语短语位于左侧。
  • strutStyle 要使用的支柱样式。支柱样式定义支柱,设置最小垂直布局度量
    • 省略或提供空值将禁用支柱StrutStyle.disabled
    • 省略或为[StrutStyle]的任何属性提供空值将导致使用默认值。强烈建议至少指定一个[fontSize]。
  • textWidthBasis 定义如何测量呈现文本的宽度
    • TextWidthBasis.longestLine
    • TextWidthBasis.parent

TextStyle参数属性

用于指定文本显示的样式如颜色、字体、粗细、背景等。我们看一个示例:

  1. Text("Hello world",
  2. style: TextStyle(
  3. color: Colors.blue,
  4. fontSize: 18.0,
  5. height: 1.2,
  6. fontFamily: "Courier",
  7. background: new Paint()..color=Colors.yellow,
  8. decoration:TextDecoration.underline,
  9. decorationStyle: TextDecorationStyle.dashed
  10. ),
  11. );

效果如图所示:
文本及样式 - 图3
此示例只展示了TextStyle的部分属性,它还有一些其它属性,属性名基本都是自解释的,在此不再赘述,读者可以查阅SDK文档了解Flutter的文本参数。值得注意的是:

  1. (new) TextStyle TextStyle({bool inherit = true,
  2. Color color,
  3. Color backgroundColor,
  4. double fontSize,
  5. FontWeight fontWeight,
  6. FontStyle fontStyle,
  7. double letterSpacing,
  8. double wordSpacing,
  9. TextBaseline textBaseline,
  10. double height,
  11. Locale locale,
  12. Paint foreground,
  13. Paint background,
  14. List<Shadow> shadows,
  15. List<FontFeature> fontFeatures,
  16. TextDecoration decoration,
  17. Color decorationColor,
  18. TextDecorationStyle decorationStyle,
  19. double decorationThickness,
  20. String debugLabel,
  21. String fontFamily,
  22. List<String> fontFamilyFallback,
  23. String package})
  • height 该属性用于指定行高,但它并不是一个绝对值,而是一个因子,具体的行高等于fontSize*height。
  • fontFamily 由于不同平台默认支持的字体集不同,所以在手动指定字体时一定要先在不同平台测试一下。
  • fontSize 该属性和Text的textScaleFactor都用于控制字体大小。但是有两个主要区别:
    • fontSize可以精确指定字体大小,而textScaleFactor只能通过缩放比例来控制。
    • textScaleFactor主要是用于系统字体大小设置改变时对Flutter应用字体进行全局调整,而fontSize通常用于单个文本,字体大小不会跟随系统字体大小变化。
  • color 绘制文本时要使用的颜色,以下是使用方法:
    • 可使用的类Color
      • Color.alphaBlend(foreground, background)
      • Color.fromARGB(a, r, g, b)
      • Color.fromRGBO(r, g, b, opacity)
      • Color.getAlphaFromOpacity(opacity)
      • Color.lerp(a, b, t)
    • Colors.xxxxxxxx
  • backgroundColor 用作文本背景的颜色,继承的是Color类
  • wordSpacing 文字间距
  • decorationStyle 绘制文本装饰的样式
    • TextDecorationStyle.dashed 虚线
    • TextDecorationStyle.dotted 细虚线
    • TextDecorationStyle.double 双实线
    • TextDecorationStyle.solid 实线
    • TextDecorationStyle.wavy 波浪形
  • fontWeight 绘制文本时使用的字体厚度(e.g., bold).
    • FontWeight.bold
    • FontWeight.w500

DefaultTextStyle

在Widget树中,文本的样式默认是可以被继承的(子类文本类组件未指定具体样式时可以使用Widget树中父级设置的默认样式)
因此,如果在Widget树的某一个节点处设置一个默认的文本样式,那么该节点的子树中所有文本都会默认使用这个样式,而 DefaultTextStyle 正是用于设置默认文本样式的。下面我们看一个例子:

  1. DefaultTextStyle(
  2. //1.设置文本默认样式
  3. style: TextStyle(
  4. color:Colors.red,
  5. fontSize: 20.0,
  6. ),
  7. textAlign: TextAlign.start,
  8. child: Column(
  9. crossAxisAlignment: CrossAxisAlignment.start,
  10. children: <Widget>[
  11. Text("hello world"),
  12. Text("I am Jack"),
  13. Text("I am Jack",
  14. style: TextStyle(
  15. inherit: false, //2.不继承默认样式
  16. color: Colors.grey
  17. ),
  18. ),
  19. ],
  20. ),
  21. );

上面代码中,我们首先设置了一个默认的文本样式,即字体为20像素(逻辑像素)、颜色为红色。然后通过DefaultTextStyle 设置给了子树Column节点处,这样一来Column的所有子孙Text默认都会继承该样式,除非Text显示指定不继承样式,如代码中注释2。示例运行效果如图3-9:
文本及样式 - 图4

Text.rich

TextSpan

在上面的例子中,Text的所有文本内容只能按同一种样式,如果我们需要对一个Text内容的不同部分按照不同的样式显示,这时就可以使用 TextSpan,它代表文本的一个“片段”。我们看看 TextSpan 的定义:

  1. (new) TextSpan TextSpan({
  2. String text,
  3. List<InlineSpan> children,
  4. TextStyle style,
  5. GestureRecognizer recognizer,
  6. String semanticsLabel})
  • style 该文本片段的样式
  • text 属性代表和内容
  • children 是一个TextSpan的数组,也就是说TextSpan可以包括其他TextSpan。
  • recognizer 用于对该文本片段上用于手势进行识别处理

下面我们看一个效果,然后用TextSpan实现它。
文本及样式 - 图5

  1. Text.rich(TextSpan(
  2. children: [
  3. TextSpan(
  4. text: "Home: "
  5. ),
  6. TextSpan(
  7. text: "https://flutterchina.club",
  8. style: TextStyle(
  9. color: Colors.blue
  10. ),
  11. recognizer: _tapRecognizer
  12. ),
  13. ]
  14. ))
  • 上面代码中,我们通过TextSpan实现了一个基础文本片段和一个链接片段,然后通过Text.rich 方法将TextSpan 添加到Text中,之所以可以这样做,是因为Text其实就是RichText的一个包装,而RichText是可以显示多种样式(富文本)的widget。
  • _tapRecognizer 它是点击链接后的一个处理器(代码已省略),关于手势识别的更多内容我们将在后面单独介绍。
  • Text.rich
    1. (new) Text Text.rich(InlineSpan textSpan, {Key key,
    2. TextStyle style,
    3. StrutStyle strutStyle,
    4. TextAlign textAlign,
    5. TextDirection textDirection, Locale locale, bool softWrap, TextOverflow overflow,
    6. double textScaleFactor,
    7. int maxLines,
    8. String semanticsLabel,
    9. TextWidthBasis textWidthBasis})

WidgetSpan

使用 WidgetSpan 能够存放不是TextSpan格式的Widget,从而形成文字环绕的效果
image.png

  1. Text.rich(TextSpan(children: [
  2. WidgetSpan(
  3. child: Visibility(
  4. visible: item.isBuySrore == true,
  5. child: Padding(
  6. padding: EdgeInsets.only(right: 4.w),
  7. child: Image.asset(
  8. getImagePath("icon_color_buy"),
  9. height: 24.w,
  10. ),
  11. ),
  12. ),
  13. ),
  14. TextSpan(
  15. text: '${item.dealerName ?? ""}',
  16. style: TextStyle(
  17. fontSize: 16.sp,
  18. color: const Color(0xd9000000),
  19. fontWeight: FontWeight.w600),
  20. )
  21. ])),

自定义字体

可以在Flutter应用程序中使用不同的字体。例如:

  • 我们可能会使用设计人员创建的自定义字体
  • 或者其它第三方的字体,如 Google Fonts 中的字体。

本节将介绍如何为Flutter应用配置字体,并在渲染文本时使用它们。 在Flutter中使用字体分两步完成。首先在pubspec.yaml中声明它们,以确保它们会打包到应用程序中。然后通过TextStyle属性使用字体

在asset中声明

要将字体文件打包到应用中,和使用其它资源一样,要先在 pubspec.yaml 中声明它。然后将字体文件复制到在pubspec.yaml 中指定的位置。如:

  1. flutter:
  2. fonts:
  3. - family: Raleway
  4. fonts:
  5. - asset: assets/fonts/Raleway-Regular.ttf
  6. - asset: assets/fonts/Raleway-Medium.ttf
  7. weight: 500
  8. - asset: assets/fonts/Raleway-SemiBold.ttf
  9. weight: 600
  10. - family: AbrilFatface
  11. fonts:
  12. - asset: assets/fonts/abrilfatface/AbrilFatface-Regular.ttf

使用字体

  1. // 声明文本样式
  2. const textStyle = const TextStyle(
  3. fontFamily: 'Raleway',
  4. );
  5. // 使用文本样式
  6. var buttonText = const Text(
  7. "Use the font for this text",
  8. style: textStyle,
  9. );

package中的字体

要使用Package中定义的字体,必须提供 package 参数。例如,假设上面的字体声明位于my_package包中。然后创建TextStyle的过程如下:

  1. const textStyle = const TextStyle(
  2. fontFamily: 'Raleway',
  3. package: 'my_package', //指定包名
  4. );

如果在package包内部使用它自己定义的字体,也应该在创建文本样式时指定 package 参数,如上例所示。

一个包也可以只提供字体文件而不需要在 pubspec.yaml 中声明。 这些文件应该存放在包的lib/文件夹中。字体文件不会自动绑定到应用程序中,应用程序可以在声明字体时有选择地使用这些字体。假设一个名为 my_package 的包中有一个字体文件:

  1. lib/fonts/Raleway-Medium.ttf

然后,应用程序可以声明一个字体,如下面的示例所示:

  1. flutter:
  2. fonts:
  3. - family: Raleway
  4. fonts:
  5. - asset: assets/fonts/Raleway-Regular.ttf
  6. - asset: packages/my_package/fonts/Raleway-Medium.ttf
  7. weight: 500

lib/是隐含的,所以它不应该包含在asset路径中

在这种情况下,由于应用程序本地定义了字体,所以在创建TextStyle时可以不指定package参数:

  1. const textStyle = const TextStyle(
  2. fontFamily: 'Raleway',
  3. );

扩展

flutter实现文字超出最大宽度显示省略号

  1. Padding(
  2. padding: EdgeInsets.only(left: 4.w),
  3. child: Container(
  4. constraints:
  5. BoxConstraints(maxWidth: 60.sp),
  6. child: Text(
  7. "华南深圳地区",
  8. style: TextStyle(
  9. fontSize: 14.sp,
  10. fontWeight: FontWeight.w500,
  11. wordSpacing: 4,
  12. overflow: TextOverflow.ellipsis,
  13. ),
  14. ),
  15. ),
  16. ),

文本换行

一些场景下直接设置 maxLines,比如说

  • 父的宽度没有设置过

    1. Text(
    2. "广州市黄埔区开发大道将军山路段黄埔工程机械园东区六号广州市黄埔区开发大道将军山路段黄埔工程机械园东区六号广州市黄埔区开发大道将军山路段黄埔工程机械园东区六号广州市黄埔区开发大道将军山路段黄埔工程机械园东区六号广州市黄埔区开发大道将军山路段黄埔工程机械园东区六号",
    3. maxLines: 4,
    4. style: TextStyle(
    5. color: Color.fromRGBO(77, 99, 104, 1),
    6. ),
    7. ),

    但是直接设置maxLines 发现有些场景会无效,这时候可以考虑使用 Flexible 或者 Expanded 组件。用方如下:
    这两个组件都需要作为row或者column的子组件使用,如主轴空间不够用,则会自动扩充至次轴,实现自动换行。

  • Expanded 组件 会尽可能的充满分布在Row, Column, 或 Flex的主轴方向上;

  • Flexible 组件 也是为小部件提供空间的,但是不会要求子空间填满可用空间。
    1. new Row(
    2. mainAxisAlignment: MainAxisAlignment.spaceBetween,
    3. children: [
    4. Text(
    5. '地址:',
    6. style: TextStyle(fontSize: 18),
    7. ),
    8. Flexible(
    9. child: Text(
    10. "广州市黄埔区开发大道将军山路段黄埔工程机械园东区六号",
    11. style: TextStyle(fontSize: 18),
    12. ),
    13. )
    14. ],
    15. )