一、TextField学习
TextField 是文本输入组件,即输入框,常用组件之一
二、TextField源码
const TextField({
Key key,
this.controller,//控制器
this.focusNode,//焦点
this.decoration = const InputDecoration(),//装饰
TextInputType keyboardType,//键盘类型,输入类型
this.textInputAction,//键盘按钮
this.textCapitalization = TextCapitalization.none,//大小写
this.style,//样式
this.strutStyle,
this.textAlign = TextAlign.start,//水平对齐方式
this.textAlignVertical,//垂直对齐方式
this.textDirection,
this.readOnly = false,//是否只能读取
ToolbarOptions toolbarOptions,//配置工具栏
this.showCursor,
this.autofocus = false,//自动获取焦点
this.obscuringCharacter = '•',
this.obscureText = false,//是否隐藏文本,密码类型
this.autocorrect = true,//自动更正
SmartDashesType smartDashesType,
SmartQuotesType smartQuotesType,
this.enableSuggestions = true,
this.maxLines = 1,//最大行数
this.minLines,//最小行数
this.expands = false,
this.maxLength,//最多输入数,不为0时右下角有计数器
this.maxLengthEnforced = true,
this.onChanged,//输入改变回调
this.onEditingComplete,//输入完成时,配合TextInputAction.done使用
this.onSubmitted,//提交时,配合TextInputAction
this.onAppPrivateCommand,
this.inputFormatters,//输入校验
this.enabled,//是否可用
this.cursorWidth = 2.0,//光标宽度
this.cursorHeight,//光标高度
this.cursorRadius,//光标圆角
this.cursorColor,//光标颜色
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.start,
this.enableInteractiveSelection = true,
this.onTap,//点击事件
this.mouseCursor,
this.buildCounter,
this.scrollController,
this.scrollPhysics,
this.autofillHints,
this.restorationId,
}) : assert(textAlign != null),
assert(readOnly != null),
assert(autofocus != null),
assert(obscuringCharacter != null && obscuringCharacter.length == 1),
assert(obscureText != null),
assert(autocorrect != null),
smartDashesType = smartDashesType ?? (obscureText ? SmartDashesType.disabled : SmartDashesType.enabled),
smartQuotesType = smartQuotesType ?? (obscureText ? SmartQuotesType.disabled : SmartQuotesType.enabled),
assert(enableSuggestions != null),
assert(enableInteractiveSelection != null),
assert(maxLengthEnforced != null),
assert(scrollPadding != null),
assert(dragStartBehavior != null),
assert(selectionHeightStyle != null),
assert(selectionWidthStyle != null),
assert(maxLines == null || maxLines > 0),
assert(minLines == null || minLines > 0),
assert(
(maxLines == null) || (minLines == null) || (maxLines >= minLines),
"minLines can't be greater than maxLines",
),
assert(expands != null),
assert(
!expands || (maxLines == null && minLines == null),
'minLines and maxLines must be null when expands is true.',
),
assert(!obscureText || maxLines == 1, 'Obscured fields cannot be multiline.'),
assert(maxLength == null || maxLength == TextField.noMaxLength || maxLength > 0),
// Assert the following instead of setting it directly to avoid surprising the user by silently changing the value they set.
assert(!identical(textInputAction, TextInputAction.newline) ||
maxLines == 1 ||
!identical(keyboardType, TextInputType.text),
'Use keyboardType TextInputType.multiline when using TextInputAction.newline on a multiline TextField.'),
keyboardType = keyboardType ?? (maxLines == 1 ? TextInputType.text : TextInputType.multiline),
toolbarOptions = toolbarOptions ?? (obscureText ?
const ToolbarOptions(
selectAll: true,
paste: true,
) :
const ToolbarOptions(
copy: true,
cut: true,
selectAll: true,
paste: true,
)),
super(key: key);
三、TextField属性说明
属性 | 说明 |
---|---|
controller | 控制器 为绑定的输入框 TextField 预设内容,TextEditingController(text:"初始化") 获取输入框内容,textEditingController.text 清空输入框内容,textEditingController.text ="",textEditingController.clear() |
focusNode | 焦点,用来控制TextField 焦点的获取与关闭,获取焦点FocusScope.of(context).requestFocus(focusNode),失去焦点,focusNode.unfocus() |
decoration | 装饰,InputDecoration详细见下文 |
keyboardType | 键盘类型,输入类型 text:通用键盘 multiline:当TextField为多行时(maxLines设置大于1),右下角的为“换行” 按键。 number:数字键盘 phone:手机键盘,比数字键盘多"*"和 "#" datetime:在ios上和text一样,在android上出现数字键盘、":"和 "-" emailAddress:邮箱键盘,有"@" 和 "."按键 url:url键盘,有"/" 和 "."按键 visiblePassword:既有字幕又有数字的键盘 |
textInputAction | 键盘右下角按钮(Android上显示的按钮大部分是不确定的) none:android上显示返回键,ios不支持。 unspecified:让操作系统自己决定哪个合适,一般情况下,android显示“完成”或者“返回”。 done:android显示代表“完成”的按钮,ios显示“Done”(中文:完成)。 go:android显示表达用户去向目的地的图标,比如向右的箭头,ios显示“Go”(中文:前往)。 search:android显示表达搜索的按钮,ios显示"Search"(中文:搜索)。 send:android显示表达发送意思的按钮,比如“纸飞机”按钮,ios显示"Send"(中文:发送)。 next:android显示表达“前进”的按钮,比如“向右的箭头”,ios显示"Next"(中文:下一项)。 previous:android显示表达“后退”的按钮,比如“向左的箭头”,ios不支持。 continueAction:android 不支持,ios仅在ios9.0+显示"Continue"(中文:继续)。 join:Android和ios显示"Join"(中文:加入)。 route:android 不支持,ios显示"Route"(中文:路线)。 emergencyCall:android 不支持,ios显示"Emergency Call"(中文:紧急电话)。 newline:android显示表达“换行”的按钮,ios显示”换行“。 |
textCapitalization | 大小写,仅仅是控制软键盘是大写模式还是小写模式,你也可以切换大小写 words:每一个单词的首字母大写。 sentences:每一句话的首字母大写。 characters:每个字母都大写 none:都小写 |
style | 样式 |
textAlign | 水平对齐方式 |
textAlignVertical | 垂直对齐方式 |
readOnly | 是否只能读,不可输入 |
toolbarOptions | 长按时弹出的菜单,有copy、cut、paste、selectAll四个选项可配置 |
autofocus | 是否自动获取焦点 |
obscuringCharacter | 密码模式下显示文本 |
obscureText | 是否隐藏文本,密码模式 |
autocorrect | 自动更正 |
maxLines | 最大行数 |
minLines | /最小行数 |
maxLength | 最多输入数,不为0时右下角有计数器 |
onChanged | 输入改变回调 |
onEditingComplete | 输入完成时,配合TextInputAction.done使用 |
onSubmitted | 提交时,配合TextInputAction |
inputFormatters | 输入校验,限制用户输入的内容 |
enabled | 是否可用 |
cursorWidth | 光标宽度 |
cursorHeight | 光标高度 |
cursorRadius | 光标圆角 |
cursorColor | 光标颜色 |
showCursor | 是否显示光标 |
onTap | 点击事件 |
四、InputDecoration的源码
const InputDecoration({
this.icon,//位于装饰器外部和输入框前面的图片
this.labelText,//用于描述输入框
this.labelStyle,// 控制labelText的样式
this.helperText,//帮助文本
this.helperStyle,//helperText的样式
this.helperMaxLines,//帮助文本的最大行数
this.hintText,//提示文本
this.hintStyle,//hintText的样式
this.hintMaxLines,//提示文本的最大行数
this.errorText,//错误文本
this.errorStyle,//errorText的样式
this.errorMaxLines,//错误文本的最大行数
@Deprecated(
'Use floatingLabelBehavior instead. '
'This feature was deprecated after v1.13.2.'
)
this.hasFloatingPlaceholder = true,//labelText是否浮动
this.floatingLabelBehavior = FloatingLabelBehavior.auto,//浮动标签应该如何显示
this.isCollapsed = false,//是否可折叠
this.isDense,//改变输入框是否为密集型
this.contentPadding,//内间距
this.prefixIcon,//位于输入框内部起始位置的图标。
this.prefixIconConstraints,//设置起始位置图片的大小
this.prefix,//预先填充的Widget
this.prefixText,//预填充的文本
this.prefixStyle, //prefixText的样式
this.suffixIcon,//位于输入框后面的图片
this.suffix,//位于输入框尾部的控件
this.suffixText,//位于尾部的填充文字
this.suffixStyle, //suffixText的样式
this.suffixIconConstraints,//设置输入框后面图片的大小
this.counter,//位于输入框右下方的小控件
this.counterText,//位于右下方显示的文本
this.counterStyle,//counterText的样式
this.filled, //如果为true,则输入使用fillColor指定的颜色填充
this.fillColor,//相当于输入框的背景颜色
this.focusColor,//获取焦点时颜色
this.hoverColor,
this.errorBorder, //errorText不为空,输入框没有焦点时要显示的边框
this.focusedBorder,//输入框有焦点时的边框
this.focusedErrorBorder,//输入框有焦点时的边框
this.disabledBorder,//输入框禁用时显示的边框
this.enabledBorder,//输入框可用时显示的边框
this.border,//正常情况下的边框
this.enabled = true,//输入框是否可用
this.semanticCounterText,
this.alignLabelWithHint,
}) : assert(enabled != null),
assert(!(prefix != null && prefixText != null), 'Declaring both prefix and prefixText is not supported.'),
assert(!(suffix != null && suffixText != null), 'Declaring both suffix and suffixText is not supported.');
五、InputDecoration的属性介绍
属性 | 说明 |
---|---|
icon | 位于装饰器外部和输入框前面的图片 |
labelText | 用于描述输入框 |
labelStyle | 控制labelText的样式,TextStyle类型 |
helperText | 帮助文本 |
helperStyle | helperText的样式,TextStyle类型 |
helperMaxLines | 帮助文本的最大行数 |
hintText | 提示文本 如果有设置labelText,输入框获取焦点,才能显示hintText |
hintMaxLines | 提示文本的最大行数 |
errorText | 错误文本 如果同时设置errorText和helperText,那么helperText会隐藏 |
errorStyle | errorText的样式,TextStyle类型 floatingLabelBehavior:FloatingLabelBehavior.auto时,且输入框获取焦点时,errorStyle设置颜色会覆盖labelText的颜色 如果同时设置errorStyle和helperStyle,helperStyle样式会隐藏 |
errorMaxLines | 错误文本的最大行数 |
hasFloatingPlaceholder | labelText是否浮动,bool类型(已弃用) 值为true,输入框获取焦点labelText会浮动到输入框顶部 值为false,输入框获取焦点,labelText会隐藏 |
floatingLabelBehavior | 浮动标签应该如何显示 FloatingLabelBehavior.never:labelText显示在输入框内,不可浮动 FloatingLabelBehavior.auto:labelText可浮动 FloatingLabelBehavior.always:labelText一直浮动在输入框上部 |
isCollapsed | 是否可折叠 |
isDense | 改变输入框是否为密集型,主要约束前置和后置图标的BoxConstraints大小 |
contentPadding | 内间距 |
prefixIcon | 位于输入框内部起始位置的图标。 |
prefixIconConstraints | 设置起始位置图片的大小 |
prefix | 预先填充的Widget,和prefixText只能同时存在一个 |
prefixText | 预填充的文本,和prefix只能同时存在一个 |
prefixStyle | prefixText的样式 |
suffixIcon | 位于输入框后面的图片 |
suffix | 位于输入框尾部的控件,和suffixText只能同时存在一个 |
suffixText | 位于尾部的填充文字,和suffix只能同时存在一个 |
suffixStyle | suffixText的样式 |
suffixIconConstraints | 设置输入框后面图片的大小 |
counter | 位于输入框右下方的小控件,不能和counterText同时使用 |
counterText | 位于右下方显示的文本,不能和counter同时使用 |
counterStyle | counterText的样式 |
filled | 如果为true,则输入使用fillColor指定的颜色填充 |
fillColor | 相当于输入框的背景颜色 |
focusColor | 获取焦点时颜色 |
hoverColor | 和鼠标有关 |
errorBorder | errorText不为空,输入框没有焦点时要显示的边框 |
focusedBorder | 输入框有焦点时的边框 |
focusedErrorBorder | errorText不为空,输入框有焦点时的边框 |
disabledBorder | 输入框禁用时显示的边框 |
enabledBorder | 输入框可用时显示的边框 |
border | 正常情况下的边框 |
enabled | 输入框是否可用 |
border的优先级
- 控件禁用时
当enabled为false时,如果指定了disabledBorder,优先使用disabledBorder,没有的话设置disabledBorder则使用border的部分样式(颜色默认是灰色) - 控件启用(enable为true),但errorText有值
输入框没有焦点时,优先使用errorBorder的样式,输入框有焦点时,优先使用focusedErrorBorder,如果这两个都没有设置则使用border的部分样式(颜色默认是红色) - 控件启用状态,且errorText没有值
输入框没有焦点时,优先使用enabledBorder ,有焦点时,优先使用focusedBorder,两者均没有指定时,使用默认的border
六、TextField、InputDecoration的demo
6.1、InputDecoration的使用
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("TextField学习"),
),
body: Container(
padding: EdgeInsets.all(15),
child: TextField(
decoration: InputDecoration(
icon: Icon(Icons.person,size: 35,color: Colors.blue,),
labelText: "我是labelText",
labelStyle: TextStyle(
fontSize: 15
),
helperText: "我是helperText",
helperStyle: TextStyle(
color: Colors.orange
),
helperMaxLines: 2,
hintText: "我是hintText我是hintText我是hintText我是hintText我是hintText我是hintText我是hintText我是hintText我是hintText我是hintText",
hintMaxLines: 1,
errorText: "我是errorText",
errorStyle: TextStyle(
color: Colors.purpleAccent,
fontSize: 12
),
//labelText是否会浮动
hasFloatingPlaceholder: true,
//labelText浮动的如何显示
floatingLabelBehavior:FloatingLabelBehavior.always,
//是否为密集型
isDense: false,
//内间距
contentPadding:EdgeInsets.fromLTRB(5, 0, 5, 0),
//位于输入框内部起始位置的图标
prefixIcon: Icon(Icons.search),
//设置起始位置图片的大小
prefixIconConstraints: BoxConstraints(minHeight: 5),
//预填充的widget
// prefix: Container(height: 10,width: 10,color: Colors.red,),
//预填充的文本
prefixText: "+86",
//位于输入框后面的图片
suffixIcon: Icon(Icons.cleaning_services),
//控制输入框后面的图片的大小
suffixIconConstraints:BoxConstraints(minHeight: 5),
//位于右下方显示的组件
// counter: Text("0/10"),
//位于右下方显示的文本
counterText: "0/10",
//是否使用fillColor颜色为输入框背景色
filled: true,
//输入框背景色
fillColor: Colors.white,
//有errorText,未获取焦点边框
errorBorder: OutlineInputBorder(
/*边角*/
borderRadius: BorderRadius.all(
Radius.circular(5), //边角为30
),
borderSide: BorderSide(
color: Colors.yellow,
width: 1
)
),
//有errorText,获取焦点边框
focusedErrorBorder: OutlineInputBorder(
/*边角*/
borderRadius: BorderRadius.all(
Radius.circular(5), //边角为30
),
borderSide: BorderSide(
color: Colors.blue,
width: 1
)
),
),
),
)),
);
6.2、TextField设置内容,并且保持光标在末尾
void main() {
runApp(TextFieldFul());
}
class TextFieldFul extends StatefulWidget {
TextFieldFul({Key key}) : super(key: key);
_TextFieldFulState createState() => _TextFieldFulState();
}
class _TextFieldFulState extends State<TextFieldFul> {
var textEditingController = TextEditingController();
@override
void initState() {
super.initState();
//初始化输入框的内容
String initStr = "ysl";
//初始化光标在文本的后面
textEditingController = TextEditingController.fromValue(
//初始化文本的显示
TextEditingValue(
//设置初始化文本
text:initStr,
//设置光标的位置
selection: TextSelection.fromPosition(
//设置文本的位置
TextPosition(
affinity: TextAffinity.downstream,
//光标向后移动的位置
offset:initStr.length
)
)
)
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("TextField学习"),
),
body: Container(
padding: EdgeInsets.all(15),
child: TextField(
controller: textEditingController,
onChanged: (value){
print(textEditingController.text);
},
autofocus: true,
),
)),
);
}
}
6.3、TextField焦点获取和失去
class _TextFieldFulState extends State<TextFieldFul> {
//焦点组件
FocusNode focusNode = FocusNode();
@override
void initState() {
super.initState();
focusNode.addListener(() {
//是否获取焦点
bool hasFocus = focusNode.hasFocus;
//是否添加了监听
bool hasListener = focusNode.hasListeners;
print("ysl--hasFocus:${hasFocus},hasListener:${hasListener}");
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("TextField学习"),
),
body: Container(
padding: EdgeInsets.all(15),
child: Column(
children: [
TextField(
autofocus: true,
focusNode: focusNode,
),
SizedBox(
height: 15,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
OutlinedButton(child: Text("获取焦点"), onPressed: () {
FocusScope.of(context).requestFocus(focusNode);
}),
OutlinedButton(child: Text("失去焦点"), onPressed: () {
focusNode.unfocus();
})
],
)
],
),
)),
);
}
}
6.4、TextField的简单使用
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("TextField学习"),
),
body: Container(
padding: EdgeInsets.all(10),
child: TextField(
//键盘类型
keyboardType: TextInputType.phone,
//键盘右下角按钮
textInputAction: TextInputAction.none,
//大小写
textCapitalization: TextCapitalization.words,
//样式
style: TextStyle(
color: Colors.red
),
//水平对齐方式
textAlign: TextAlign.center,
//垂直对齐方式
textAlignVertical: TextAlignVertical.center,
//是否只读
readOnly: false,
//长按时弹出的菜单
toolbarOptions:ToolbarOptions(
copy: true,
cut: true,
paste: true,
selectAll: true
) ,
//是否自动获取焦点
autofocus: false,
//密码模式
obscureText: true,
//密码模式下显示文本
obscuringCharacter: "*",
//光标宽度
cursorWidth: 5,
cursorHeight: 10,
//是否显示光标
showCursor: true,
//最多输入数量
maxLength: 11,
onTap: (){
print("点击了输入框");
},
),
)),
);