Text Widget

Text Widgets是Flutter中一个十分常用的一个Widget,类似于Android平台下的TextView,几乎在每个App的UI中都会或多或少的出现它的身影,让我们去一睹Text的风采吧!

  • 简单Text使用 ```dart import ‘package:flutter/material.dart’;

void main() { runApp(new MaterialApp(home: new TextDemo())); }

class TextDemo extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text(“Hello Flutter”), ), body: new Center( child: new Text( “This is Flutter Widget —— Text ,is a StatelessWidget”, style: new TextStyle( fontStyle: FontStyle.italic, fontSize: 20.0, color: Colors.red, ), textAlign: TextAlign.center, )), ); } }

  1. - 效果图
  2. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/467623/1610956801538-c9e51e96-478a-4c2e-8678-3d075b9511e8.png#align=left&display=inline&height=608&margin=%5Bobject%20Object%5D&name=image.png&originHeight=608&originWidth=365&size=35641&status=done&style=none&width=365)
  3. Flutter中的Text WidgetAndroid平台下的TextView十分类似,我们也可以跟在原生Android平台下一样的指定Text显示的样式,文字大小,颜色等,来一起看一下Flutter中关于Text的构造方法,以及Text里面有哪些属性可供开发者自己定制。
  4. ```dart
  5. const Text(this.data, {
  6. Key key,//Text显示的内容
  7. this.style, //Text显示的样式
  8. this.textAlign,//文本应该如何水平对齐,TextAlign.start,end 或者center
  9. this.textDirection, //文本方向,TextDirection.ltr\TextDirection.rtl
  10. this.locale,
  11. this.softWrap, //是否自动换行,若为false,文字将不考虑容器大小,单行显示,超出屏幕部分将默认截断处理
  12. this.overflow, //当文字超出屏幕的时候,如何处理,TextOverflow.clip(裁剪)\TextOverflow.fade(渐隐)\TextOverflow.ellipsis(省略号)
  13. this.textScaleFactor, //字体显示倍率,上面的例子使用的字体大小是20.0,将字体设置成10.0,然后倍率为2
  14. this.maxLines, //最大行数设置
  15. this.semanticsLabel,
  16. })

上述的属性中,我们使用的最多的就是TextStyle属性了,比如我们想自己设定Text显示的颜色,大小,或者下划线、删除线等等各种各样的奇葩样式都可以通过TextStyle来指定,看下TextStyle的构造方法说明:

  1. const TextStyle({
  2. this.inherit: true, // 为false的时候不显示
  3. this.color, // 颜色
  4. this.fontSize, // 字号
  5. this.fontWeight, // 字重,加粗也用这个字段 FontWeight.w700
  6. this.fontStyle, // FontStyle.normal FontStyle.italic斜体
  7. this.letterSpacing, // 字符间距 就是单个字母或者汉字之间的间隔,可以是负数
  8. this.wordSpacing, // 字间距 句字之间的间距
  9. this.textBaseline, // 基线,两个值,字面意思是一个用来排字母的,一人用来排表意字的(类似中文)
  10. this.height, // 当用来Text控件上时,行高(会乘以fontSize,所以不以设置过大)
  11. this.decoration, // 添加上划线,下划线,删除线
  12. this.decorationColor, // 划线的颜色
  13. this.decorationStyle, // 这个style可能控制画实线,虚线,两条线,点, 波浪线等
  14. this.debugLabel,
  15. String fontFamily, // 字体
  16. String package,
  17. })

TextStyle里面的样式我就不逐个为大家贴效果图了,读者可自行模拟测试下期基本用户,我贴上我的全部样例代码跟统一的效果图供大家参考。

  • 效果图

image.png

  • 上图的完整示例代码
  1. import 'package:flutter/material.dart';
  2. void main() {
  3. runApp(new MaterialApp(home: new TextDemo()));
  4. }
  5. class TextDemo extends StatelessWidget {
  6. @override
  7. Widget build(BuildContext context) {
  8. return new Scaffold(
  9. appBar: new AppBar(
  10. title: new Text("Hello Flutter"),
  11. ),
  12. body: new Center(
  13. child: new Column(
  14. crossAxisAlignment: CrossAxisAlignment.center,
  15. children: <Widget>[
  16. new Text(
  17. 'inherit: 为 false 的时候不显示',
  18. style: new TextStyle(
  19. fontSize: 18.0,
  20. color: Colors.redAccent,
  21. inherit: true,
  22. ),
  23. ),
  24. new Text(
  25. 'color/fontSize: 字体颜色,字号等',
  26. style: new TextStyle(
  27. color: Color.fromARGB(255, 150, 150, 150),
  28. fontSize: 22.0,
  29. ),
  30. ),
  31. new Text(
  32. 'fontWeight: 字重',
  33. style: new TextStyle(
  34. fontSize: 18.0,
  35. color: Colors.redAccent,
  36. fontWeight: FontWeight.w700),
  37. ),
  38. new Text(
  39. 'fontStyle: FontStyle.italic 斜体',
  40. style: new TextStyle(
  41. fontStyle: FontStyle.italic,
  42. ),
  43. ),
  44. new Text(
  45. 'letterSpacing: 字符间距',
  46. style: new TextStyle(
  47. letterSpacing: 10.0,
  48. // wordSpacing: 15.0
  49. ),
  50. ),
  51. new Text(
  52. 'wordSpacing: 字或单词间距',
  53. style: new TextStyle(
  54. // letterSpacing: 10.0,
  55. wordSpacing: 15.0),
  56. ),
  57. new Text(
  58. 'textBaseline:这一行的值为TextBaseline.alphabetic',
  59. style: new TextStyle(textBaseline: TextBaseline.alphabetic),
  60. ),
  61. new Text(
  62. 'textBaseline:这一行的值为TextBaseline.ideographic',
  63. style: new TextStyle(textBaseline: TextBaseline.ideographic),
  64. ),
  65. new Text('height: 用在Text控件上的时候,会乘以fontSize做为行高,所以这个值不能设置过大',
  66. style: new TextStyle(
  67. height: 1.0,
  68. )),
  69. new Text('decoration: TextDecoration.overline 上划线',
  70. style: new TextStyle(
  71. fontSize: 18.0,
  72. color: Colors.redAccent,
  73. decoration: TextDecoration.overline,
  74. decorationStyle: TextDecorationStyle.wavy)),
  75. new Text('decoration: TextDecoration.lineThrough 删除线',
  76. style: new TextStyle(
  77. decoration: TextDecoration.lineThrough,
  78. decorationStyle: TextDecorationStyle.dashed)),
  79. new Text('decoration: TextDecoration.underline 下划线',
  80. style: new TextStyle(
  81. fontSize: 18.0,
  82. color: Colors.redAccent,
  83. decoration: TextDecoration.underline,
  84. decorationStyle: TextDecorationStyle.dotted)),
  85. ],
  86. ),
  87. ));
  88. }
  89. }


TextField

通过对Text的学习我们了解到Text是用于显示文本的,如果对显示的文本有一些特殊的要求,比如字体样式,文字颜色我们可以通过TextStyle去给Text指定style来做个性化定制,这一点跟原生Android的TextView非常类似,有了文字显示就肯定会有文字输入,今天我们就一起来学习一下Flutter中的文字输入Widget TextField。

先来看下TextField的构造方法

  1. const TextField({
  2. Key key,
  3. this.controller, 控制器,控制TextField文字
  4. this.focusNode,
  5. this.decoration = const InputDecoration(), //输入器装饰
  6. TextInputType keyboardType, 输入的类型
  7. this.textInputAction,
  8. this.textCapitalization = TextCapitalization.none,
  9. this.style,
  10. this.textAlign = TextAlign.start, //文字显示位置
  11. this.autofocus = false,
  12. this.obscureText = false,
  13. this.autocorrect = true,
  14. this.maxLines = 1,
  15. this.maxLength,
  16. this.maxLengthEnforced = true,
  17. this.onChanged, //文字改变触发
  18. this.onEditingComplete, //当用户提交可编辑内容时调用
  19. this.onSubmitted, 文字提交触发(键盘按键)
  20. this.inputFormatters,
  21. this.enabled,
  22. this.cursorWidth = 2.0,
  23. this.cursorRadius,
  24. this.cursorColor,
  25. this.keyboardAppearance,
  26. this.scrollPadding = const EdgeInsets.all(20.0),
  27. })

4. Flutter 常用组件 - 图2

通过上面的构造方法跟预览效果图,熟悉android开发的小伙伴们是不是有种似曾相识的感觉,Flutter的TextField跟原生Android中的EditText用法包括部分属性名几乎都是一样的,比如我们可以通过keyboardType来指定唤起软件盘时的输入方式,例如上图的两个输入框属性设置:

  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3. void main() {
  4. runApp(new MaterialApp(home: new PullToRefreshDemo()));
  5. }
  6. class PullToRefreshDemo extends StatelessWidget {
  7. @override
  8. Widget build(BuildContext context) {
  9. return Scaffold(
  10. appBar: new AppBar(
  11. title: new Text("文本输入"),
  12. ),
  13. body: new Center(
  14. child: new Column(
  15. children: <Widget>[
  16. new Text("简单文本输入框",style: new TextStyle(fontSize: 20.0)),
  17. new TextField(keyboardType: TextInputType.text,), //指定输入方式为文本输入
  18. new TextField(keyboardType: TextInputType.number,),//指定唤起软键盘时默认显示数字键盘
  19. ],
  20. )),
  21. );
  22. }
  23. }

通过上面的构造方法我们留意到TextField给我提供了onChanged、onSubmitted、OnEditingComplete回调方法帮助我们监听输入框的内容变化、编辑提交、编辑完成等事件,我们给输入框绑定上述监听方法做下测试:

  1. new TextField(
  2. onSubmitted: (value){
  3. print("------------文字提交触发(键盘按键)--");
  4. },
  5. onEditingComplete: (){
  6. print("----------------编辑完成---");
  7. },
  8. onChanged: (value){
  9. print("----------------输入框中内容为:$value--");
  10. },
  11. keyboardType: TextInputType.text,
  12. ),

唤起软键盘后在输入框中输入123456,log控制台打印出:

image.png

到此对输入框的基本使用你已经完全get到了,但是现实开发过程中,可能我们会需要给输入框指定一些辅助性的说明内容,比如输入框未输入内容时添加hint提示,或者在输入框的旁边添加Icon指示,或者输入框内部文字的显示样式、背景色等等,这些辅助性的设置在Flutter中统一有一个叫做InputDecoration的装饰器来完成操作,我们先来看下InputDecoration的构造方法,然后来简单尝试下几个日常开发中常用的操作。

  1. const InputDecoration({
  2. this.icon, //输入框左侧添加个图标
  3. this.labelText,//输入框获取焦点/有内容 会移动到左上角,否则在输入框内labelTex的位置
  4. this.labelStyle,
  5. this.helperText,
  6. this.helperStyle,
  7. this.hintText, //未输入文字时,输入框中的提示文字
  8. this.hintStyle,
  9. this.errorText,
  10. this.errorStyle,
  11. this.errorMaxLines,
  12. this.isDense,
  13. this.contentPadding,
  14. this.prefixIcon, //输入框内侧左面的控件
  15. this.prefix,
  16. this.prefixText,
  17. this.prefixStyle,
  18. this.suffixIcon,//输入框内侧右面的图标
  19. this.suffix,
  20. this.suffixText,
  21. this.suffixStyle,
  22. this.counterText,
  23. this.counterStyle,
  24. this.filled,
  25. this.fillColor,
  26. this.errorBorder,
  27. this.focusedBorder,
  28. this.focusedErrorBorder,
  29. this.disabledBorder,
  30. this.enabledBorder,
  31. this.border, //增加一个边框
  32. this.enabled = true,
  33. this.semanticCounterText,
  34. })

给输入框添加输入辅助性输入说明:

  1. body: new Center(
  2. child: new TextField(
  3. decoration: new InputDecoration(
  4. labelText: "请输入内容",//输入框内无文字时提示内容,有内容时会自动浮在内容上方
  5. helperText: "随便输入文字或数字", //输入框底部辅助性说明文字
  6. prefixIcon: new Icon(Icons.print), //输入框左边图标
  7. suffixIcon: new Icon(Icons.picture_as_pdf), //输入框右边图片
  8. contentPadding: const EdgeInsets.only(bottom:15.0)),
  9. keyboardType: TextInputType.number,
  10. ),
  11. ));

image.png
通过给InputDecoration设置border给输入框添加边框:

  1. body: new Center(
  2. child: new TextField(
  3. decoration: new InputDecoration(
  4. border: new OutlineInputBorder( //添加边框
  5. gapPadding: 10.0,
  6. borderRadius: BorderRadius.circular(20.0),
  7. ),
  8. prefixIcon: new Icon(Icons.print),
  9. contentPadding: const EdgeInsets.all(15.0)),
  10. keyboardType: TextInputType.number,
  11. ),
  12. ));

image.png

其他样式跟属性读者可自行运行体验,我就不逐一列举说明了,总之参考文档再结合原生开发的经验去使用TextField还是比较简单的。下面我分享一个完整的登录UI的例子供大家参考:

4. Flutter 常用组件 - 图6

完整代码:

  1. import 'package:flutter/material.dart';
  2. void main() {
  3. runApp(new MaterialApp(home: new MyApp()));
  4. }
  5. class MyApp extends StatefulWidget {
  6. @override
  7. State<StatefulWidget> createState() {
  8. return new MyAppState();
  9. }
  10. }
  11. class MyAppState extends State<MyApp> {
  12. @override
  13. Widget build(BuildContext context) {
  14. TextEditingController _userPhoneController = new TextEditingController();
  15. TextEditingController _userPasswordController = new TextEditingController();
  16. /**
  17. * 清空输入框内容
  18. */
  19. void onTextClear() {
  20. setState(() {
  21. _userPhoneController.text = "";
  22. _userPasswordController.text = "";
  23. });
  24. }
  25. return new Scaffold(
  26. appBar: new AppBar(
  27. title: new Text("登录"),
  28. ),
  29. body: new Column(
  30. children: <Widget>[
  31. new TextField(
  32. controller: _userPhoneController,
  33. keyboardType: TextInputType.number,
  34. decoration: new InputDecoration(
  35. contentPadding: const EdgeInsets.all(10.0),
  36. icon: new Icon(Icons.phone),
  37. labelText: "请输入手机号",
  38. helperText: "注册时填写的手机号"),
  39. onChanged: (String str) {
  40. //onChanged是每次输入框内每次文字变更触发的回调
  41. print('手机号为:$str----------');
  42. },
  43. onSubmitted: (String str) {
  44. //onSubmitted是用户提交而触发的回调{当用户点击提交按钮(输入法回车键)}
  45. print('最终手机号为:$str---------------');
  46. },
  47. ),
  48. new TextField(
  49. controller: _userPasswordController,
  50. keyboardType: TextInputType.text,
  51. decoration: new InputDecoration(
  52. contentPadding: const EdgeInsets.all(10.0),
  53. icon: new Icon(Icons.nature_people),
  54. labelText: "请输入名字",
  55. // hintText: "fdsfdss",
  56. helperText: "注册名字"),
  57. ),
  58. new Builder(builder: (BuildContext context) {
  59. return new RaisedButton(
  60. onPressed: () {
  61. if (_userPasswordController.text.toString() == "10086" &&
  62. _userPhoneController.text.toString() == "10086") {
  63. Scaffold.of(context)
  64. .showSnackBar(new SnackBar(content: new Text("校验通过")));
  65. } else {
  66. Scaffold.of(context)
  67. .showSnackBar(new SnackBar(content: new Text("校验有问题,请重新输入")));
  68. onTextClear(); //情况输入内容,让用户重新输入
  69. }
  70. },
  71. color: Colors.blue,
  72. highlightColor: Colors.deepPurple,
  73. disabledColor: Colors.cyan,
  74. child: new Text(
  75. "登录",
  76. style: new TextStyle(color: Colors.white),
  77. ),
  78. );
  79. })
  80. ],
  81. ));
  82. }
  83. }