老孟导读:你们好,这是【Flutter实战】系列文章的第二篇,这一篇讲解文本组件,文本组件包括文本展现组件(Text和RichText)和文本输入组件(TextField),基础用法和五个案例助你快速掌握。
第一篇连接: 【Flutter实战】移动技术发展史
Text是显示文本的组件,最经常使用的组件,没有之一。基本用法以下:前端
Text('老孟')
注意:Text组件必定要包裹在Scaffold组件下,不然效果以下:android
文本的样式在style
中设置,类型为TextStyle
,TextStyle
中包含不少文本样式属性,下面介绍一些经常使用的。ios
设置文本大小和颜色:git
Text('老孟',style: TextStyle(color: Colors.red,fontSize: 20),),
上面黑色的字体为没有设置的效果,做为对比。github
设置字体粗细:api
Text('老孟',style: TextStyle(fontWeight: FontWeight.bold))
字体粗细共有9个级别,为w100
至w900
,FontWeight.bold是w700
。微信
设置斜体:ide
Text('老孟',style: TextStyle(fontStyle: FontStyle.italic,))
设置自定义的字体:post
pubspec.yaml
:fonts: - family: maobi fonts: - asset: assets/fonts/maobi.ttf
maobi:是本身对当前字体的命名,有意义便可。字体
asset:字体文件的目录。
使用:
Text('老孟', style: TextStyle(fontFamily: 'maobi',)),
设置对齐方式:
Container( height: 100, width: 200, color: Colors.blue.withOpacity(.4), child: Text('老孟', textAlign: TextAlign.center), ),
textAlign
只是控制水平方向的对齐方式,值说明以下:
TextDirection
属性有关,若是设置TextDirection.ltr
,则左对齐,设置TextDirection.rtl
则右对齐。TextDirection
属性有关,若是设置TextDirection.ltr
,则右对齐,设置TextDirection.rtl
则左对齐。设置文本自动换行:
Container( height: 100, width: 200, color: Colors.blue.withOpacity(.4), child: Text('老孟,专一分享Flutter技术和应用实战',softWrap: true,), )
文本超出范围时的处理:
Container( height: 100, width: 200, color: Colors.blue.withOpacity(.4), child: Text('老孟,专一分享Flutter技术和应用实战',overflow: TextOverflow.ellipsis,), )
溢出的处理方式:
设置全局字体样式:
在MaterialApp
的theme
中设置以下
MaterialApp( title: 'Flutter Demo', theme: ThemeData( ... textTheme: TextTheme( bodyText2: TextStyle(color: Colors.red,fontSize: 24), ) ), home: Scaffold( body: TextDemo(), ), )
Text组件默认为红色,
Text('老孟'), Text('老孟',style: TextStyle(color: Colors.blue,fontSize: 20),),
RichText的属性和Text基本同样,使用以下:
RichText( text: TextSpan( style: DefaultTextStyle.of(context).style, children: <InlineSpan>[ TextSpan(text: '老孟', style: TextStyle(color: Colors.red)), TextSpan(text: ','), TextSpan(text: '专一分享Flutter技术和应用实战'), ]), )
TextField是文本输入组件,即输入框,经常使用组件之一。基本用法:
TextField()
不须要任何参数,一个最简单的文本输入组件就出来了,效果以下:
decoration
是TextField组件的装饰(外观)参数,类型是InputDecoration。
icon
显示在输入框的前面,用法以下:
TextField( decoration: InputDecoration( icon: Icon(Icons.person), ), )
当输入框是空并且没有焦点时,labelText显示在输入框上边,当获取焦点或者不为空时labelText往上移动一点,labelStyle
参数表示文本样式,具体参考TextStyle
, 用法以下:
TextField( decoration: InputDecoration( labelText: '姓名:', labelStyle: TextStyle(color:Colors.red) ), )
hasFloatingPlaceholder
参数控制当输入框获取焦点或者不为空时是否还显示labelText
,默认为true,显示。
helperText
显示在输入框的左下部,用于提示用户,helperStyle
参数表示文本样式,具体参考TextStyle
用法以下:
TextField( decoration: InputDecoration( helperText: '用户名长度为6-10个字母', helperStyle: TextStyle(color: Colors.blue), helperMaxLines: 1 ), )
hintText
是当输入框为空时的提示,不为空时不在显示,用法以下:
TextField( decoration: InputDecoration( hintText: '请输入用户名', hintStyle: TextStyle(color: Colors.grey), hintMaxLines: 1 ), )
errorText
显示在输入框的左下部,默认字体为红色,用法以下:
TextField( decoration: InputDecoration( errorText: '用户名输入错误', errorStyle: TextStyle(fontSize: 12), errorMaxLines: 1, errorBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.red)), ), )
prefix
系列的组件是输入框前面的部分,用法以下:
TextField( decoration: InputDecoration( prefixIcon: Icon(Icons.person) ), )
注意prefix和icon的区别,icon是在输入框边框的外部,而prefix在里面。
suffix和prefix相反,suffix在输入框的尾部,用法以下:
TextField( decoration: InputDecoration( suffixIcon: Icon(Icons.person) ), )
counter
组件统计输入框文字的个数,counter仅仅是展现效果,不具有自动统计字数的功能, 自动统计字数代码以下:
var _textFieldValue = ''; TextField( onChanged: (value){ setState(() { _textFieldValue = value; }); }, decoration: InputDecoration( counterText: '${_textFieldValue.length}/32' ), )
filled
为true时,输入框将会被fillColor
填充,仿QQ登陆输入框代码以下:
Container( height: 60, width: 250, child: TextField( decoration: InputDecoration( fillColor: Color(0x30cccccc), filled: true, enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0x00FF0000)), borderRadius: BorderRadius.all(Radius.circular(100))), hintText: 'QQ号/手机号/邮箱', focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0x00000000)), borderRadius: BorderRadius.all(Radius.circular(100))), ), ), )
controller
是输入框文本编辑的控制器,能够获取TextField的内容、设置TextField的内容,下面将输入的英文变为大写:
TextEditingController _controller; @override void initState() { super.initState(); _controller = TextEditingController() ..addListener(() { //获取输入框的内容,变为大写 _controller.text = _controller.text.toUpperCase(); }); } @override Widget build(BuildContext context) { return TextField( controller: _controller, ); } @override dispose() { super.dispose(); _controller.dispose(); }
有时输入框后面带有“清除”功能,须要controller来实现。若是须要2个TextField的内容进行同步,只须要给2个TextField设置同一个controller便可实现。
keyboardType
参数控制软键盘的类型,说明以下:
textInputAction
参数控制软键盘右下角的按键,说明以下:
你们可能发现了,Android上显示的按钮大部分是不肯定的,好比next
有的显示向右的箭头,有的显示前进,这是由于各大厂商对Android ROM定制引起的。
textCapitalization
参数是配置键盘是大写仍是小写,仅支持键盘模式为text
,其余模式下忽略此配置,说明以下:
这里仅仅是控制软键盘是大写模式仍是小写模式,你也能够切换大小写,系统并不会改变输入框内的内容。
textAlignVertical
表示垂直方向的对齐方式,textDirection
表示文本方向,用法以下:
TextField( textAlignVertical: TextAlignVertical.center, textDirection: TextDirection.rtl, )
toolbarOptions
表示长按时弹出的菜单,有copy
、cut
、paste
、selectAll
,用法以下:
TextField( toolbarOptions: ToolbarOptions( copy: true, cut: true, paste: true, selectAll: true ), )
cursor
表示光标,用法以下:
TextField( showCursor: true, cursorWidth: 3, cursorRadius: Radius.circular(10), cursorColor: Colors.red, )
效果以下:
将输入框设置为密码框,只需obscureText
属性设置true便可,用法以下:
TextField( obscureText: true, )
经过inputFormatters
能够限制用户输入的内容,好比只想让用户输入字符,设置以下:
TextField( inputFormatters: [ WhitelistingTextInputFormatter(RegExp("[a-zA-Z]")), ], )
这时用户是没法输入数字的。
onChanged
是当内容发生变化时回调,onSubmitted
是点击回车或者点击软键盘上的完成回调,onTap
点击输入框时回调,用法以下:
TextField( onChanged: (value){ print('onChanged:$value'); }, onEditingComplete: (){ print('onEditingComplete'); }, onTap: (){ print('onTap'); }, )
输入框右下角常常须要字数统计,除了使用上面介绍的方法外,还可使用buildCounter
,建议使用此方法,用法以下:
TextField( maxLength: 100, buildCounter: ( BuildContext context, { int currentLength, int maxLength, bool isFocused, }) { return Text( '$currentLength/$maxLength', ); }, )
动态获取焦点
FocusScope.of(context).requestFocus(_focusNode);
_focusNode
为TextField的focusNode:
_focusNode = FocusNode(); TextField( focusNode: _focusNode, ... )
动态失去焦点
_focusNode.unfocus();
Builder( builder: (BuildContext context) { RenderBox box = context.findRenderObject(); final Shader linearGradient = LinearGradient( colors: <Color>[Colors.purple, Colors.blue], ).createShader( Rect.fromLTWH(0.0, 0.0, box?.size?.width, box?.size?.height)); return Text( '老孟,专一分享Flutter技术和应用实战', style: new TextStyle( fontSize: 18.0, fontWeight: FontWeight.bold, foreground: Paint()..shader = linearGradient), ); }, )
Builder
组件是为了计算当前Text组件大小,生成LinearGradient。
RichText( text: TextSpan( style: DefaultTextStyle.of(context).style, children: <InlineSpan>[ WidgetSpan( child: Container( margin: EdgeInsets.only(right: 10), padding: EdgeInsets.symmetric(horizontal: 10), decoration: BoxDecoration( shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(20)), color: Colors.blue), child: Text( '判断题', style: TextStyle(color: Colors.white), ), )), TextSpan(text: '泡沫灭火器可用于带电灭火'), ]), )
一般在登陆页面的底部会出现登陆即表明赞成并阅读 《服务协议》,其中《服务协议》为蓝色且可点击:
Text.rich( TextSpan( text: '登陆即表明赞成并阅读', style: TextStyle(fontSize: 11, color: Color(0xFF999999)), children: [ TextSpan( text: '《服务协议》', style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold), recognizer: TapGestureRecognizer() ..onTap = () { print('onTap'); }, ), ]), )
TextField( decoration: InputDecoration( fillColor: Color(0x30cccccc), filled: true, enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0x00FF0000)), borderRadius: BorderRadius.all(Radius.circular(100))), hintText: '输入密码', focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0x00000000)), borderRadius: BorderRadius.all(Radius.circular(100))), ), textAlign: TextAlign.center, obscureText: true, onChanged: (value) { }, )
Text.rich( TextSpan( text: '回复', style: TextStyle(fontSize: 11, color: Color(0xFF999999)), children: [ TextSpan( text: '@老孟:', style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold), recognizer: TapGestureRecognizer() ..onTap = () { print('onTap'); }, ), TextSpan( text: '你好,想知道Flutter发展前景如何?', ), ]), )
老孟Flutter博客地址(330个控件用法):http://laomengit.com
欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:
![]() |
![]() |