前言
本章介紹Flutter中文本輸入框Widget - TextField
,在實(shí)際項(xiàng)目中輸入框可謂是不可缺少的,無(wú)論是注冊(cè)登錄還是意見(jiàn)反饋,直至到評(píng)論這些很常見(jiàn)到功能都需要用戶進(jìn)行輸入操作,那Flutter中如何使用TextField進(jìn)行文本輸入呢,下面我們來(lái)介紹下。
使用方式
最簡(jiǎn)單的使用方式:
TextField()
效果如下:

源碼分析
下面我們看下TextFiled的源碼
const TextField({
Key key,//Widget的標(biāo)識(shí)
this.controller,//控制TextField的編輯,不設(shè)置會(huì)有默認(rèn)值,類型是TextEditingController
this.focusNode,//用于控制TextField是否有當(dāng)前鍵盤(pán)的輸入焦點(diǎn),類型是FocusNode
this.decoration = const InputDecoration(),//用于控制TextField的外觀顯示,如顏色,邊框等,類型是InputDecoration
TextInputType keyboardType,//用于設(shè)置該輸入框默認(rèn)的鍵盤(pán)輸入類型,類型是TextInputType
this.textInputAction,//鍵盤(pán)動(dòng)作按鈕圖標(biāo)(即回車(chē)鍵位圖標(biāo)),類型是TextInputAction
this.textCapitalization = TextCapitalization.none,//定義文本的大寫(xiě)格式,類型是TextCapitalization
this.style,//文本樣式,類型是TextStyle
this.strutStyle,//使用的支柱風(fēng)格,類型是StrutStyle
this.textAlign = TextAlign.start,//文本的對(duì)齊方式,類型是TextAlign
this.textAlignVertical,//垂直對(duì)齊,類型是TextAlignVertical
this.textDirection,//文字方向,類型TextDirection
this.readOnly = false,//bool類型,文本是不是不能編輯
this.showCursor,//bool類型,是否顯示光標(biāo)
this.autofocus = false,//類型是bool,是否自動(dòng)獲取焦點(diǎn)
this.obscureText = false,//類型是bool,是否隱藏正在編輯的文本,用于密文等,文本內(nèi)容會(huì)用“?”替換,默認(rèn)為false
this.autocorrect = true,//類型是bool,是否自動(dòng)更正
this.maxLines = 1,//類型是int,顯示的最大行數(shù)
this.minLines,//類型是int,最小展示行數(shù)
this.expands = false,//bool 類型,是否可擴(kuò)展
this.maxLength,//類型是int,輸入框中允許的最大字?jǐn)?shù)
/**
* 類型是bool,是否強(qiáng)制限制最大字符數(shù),默認(rèn)為true
* true:強(qiáng)制限制最大字符數(shù)
* false:不限制最大字符數(shù),即使設(shè)置了maxLength也不生效
**/
this.maxLengthEnforced = true,
this.onChanged,//輸入框內(nèi)容改變時(shí)的回調(diào)函數(shù),類型是ValueChanged
this.onEditingComplete,//輸入框輸入完成時(shí)觸發(fā),但是onEditingComplete沒(méi)有參數(shù),不會(huì)返回內(nèi)容,類型是VoidCallback
this.onSubmitted,//輸入框輸入完成時(shí)觸發(fā),但是onSubmitted有參數(shù),會(huì)返回內(nèi)容,類型是ValueChanged
this.inputFormatters,//用于指定輸入格式;當(dāng)用戶輸入內(nèi)容改變時(shí),會(huì)根據(jù)指定的格式來(lái)校驗(yàn)。類型是List< TextInputFormatter>
/**
* 類型是bool,輸入框是否禁用,如果為false,則輸入框會(huì)被禁用
* ,禁用狀態(tài)不接收輸入和事件,同時(shí)* * 顯示禁用態(tài)樣式(在其
* decoration中定義)。
**/
this.enabled,
this.cursorWidth = 2.0,//類型是double,自定義輸入框光標(biāo)寬度
this.cursorRadius,//自定義輸入框光標(biāo)圓角,類型是Radius
this.cursorColor,//自定義光標(biāo)顏色,類型是Color
this.keyboardAppearance,//設(shè)置鍵盤(pán)的外觀模式,只能在iOS上使用,類型是Brightness
this.scrollPadding = const EdgeInsets.all(20.0),//文本框滑動(dòng)時(shí)的間距,類型是EdgeInsets
this.dragStartBehavior = DragStartBehavior.start,//設(shè)置設(shè)置決定了用戶何時(shí)正式啟動(dòng)拖動(dòng),類型是DragStartBehavior
this.enableInteractiveSelection,//類型是bool 是否啟用交互式選擇,true:長(zhǎng)按將會(huì)選中文字,并且彈出 cut/copy/paste 的菜單
this.onTap,//TextField的點(diǎn)擊事件,類型是GestureTapCallback
this.buildCounter,//生成自定義 InputDecorator.counter 小部件的回調(diào),類型是InputCounterWidgetBuilder
this.scrollController,//類型是ScrollController,滾動(dòng)監(jiān)聽(tīng)器
this.scrollPhysics,//類型是 ScrollPhysics,確定滾動(dòng)的物理屬性
}) : assert(textAlign != null),
assert(readOnly != null),
assert(autofocus != null),
assert(obscureText != null),
assert(autocorrect != null),
assert(maxLengthEnforced != null),
assert(scrollPadding != null),
assert(dragStartBehavior != 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(maxLength == null || maxLength == TextField.noMaxLength || maxLength > 0),
keyboardType = keyboardType ?? (maxLines == 1 ? TextInputType.text : TextInputType.multiline),
super(key: key);
注:TextField中的參數(shù)都是可選的
下面看下TextField中獲取輸入內(nèi)容的兩種方法
- TextEditingController
TextEditingController是TextField的控制類,可以控制Textfield的編輯,是TextField的controller屬性,我們可以給TextField賦值自己創(chuàng)建的TextEditingController對(duì)象來(lái)控制TextField,使用方式如下:
class _MyHomePageState extends State<MyHomePage> {
TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
widget.title,
textWidthBasis: TextWidthBasis.parent,
),
),
body: TextField(
controller: _controller,
));
}
}
然后我們就可以用_controller.text來(lái)訪問(wèn)TextField里的內(nèi)容了。
- ValueChanged
當(dāng)用戶輸入,TextField的內(nèi)容發(fā)生變化,TextField就會(huì)回調(diào)它的onChanged回調(diào)。因此onChanged可以實(shí)時(shí)查看TextField的內(nèi)容變化
使用方法:
onChanged: (String data){
//實(shí)時(shí)獲取
print(data);
},
- FocusNode
使用方式
FocusNode()
源碼分析
FocusNode({
String debugLabel,//String類型,設(shè)置debug標(biāo)簽,這樣不會(huì)影響release環(huán)境
FocusOnKeyCallback onKey,//獲取焦點(diǎn)回調(diào),類型是FocusOnKeyCallback
this.skipTraversal = false,//bool類型是否跳過(guò)焦點(diǎn)遍歷事件,默認(rèn)為false
}) : assert(skipTraversal != null),
_onKey = onKey {
// Set it via the setter so that it does nothing on release builds.
this.debugLabel = debugLabel;
}
- InputDecoration
const InputDecoration({
this.icon,//圖片,類型是Widget
this.labelText,//String 類型,描述輸入字段的文本
this.labelStyle,//lableText樣式,類型是TextStyle
this.helperText,//String 提供有關(guān)輸入的提示文本,比如改如何使用
this.helperStyle,//helperText的樣式,類型是TextStyle
this.hintText,//String類型,指示字段接受何種類型的輸入
this.hintStyle,//hintText的樣式,類型是TextStyle
this.hintMaxLines,//int 類型,[hintText]所能占用的最大行數(shù)。
this.errorText,//String類型,出現(xiàn)在輸入邊框下方的錯(cuò)誤提示文本。
this.errorStyle,//errorText的樣式,類型是TextStyle
this.errorMaxLines,//int 類型,errorMaxLines所能占用的最大行數(shù)。
this.hasFloatingPlaceholder = true,//bool類型,標(biāo)簽是否在焦點(diǎn)上浮動(dòng)
this.isDense,//bool 類型,輸入是否為密集形式(即使用較少的垂直空間)。
this.contentPadding,//輸入內(nèi)容的那邊距,類型是EdgeInsetsGeometry
this.prefixIcon,//出現(xiàn)在前綴或裝飾器文本字段的可編輯部分之前的圖標(biāo),類型為Widget
this.prefix,//可選小部件放置在輸入之前的行上,類型為Widget
this.prefixText,//String 類型可選文本前綴,放在輸入之前的行上
this.prefixStyle,//prefixText的樣式,類型為T(mén)extStyle
this.suffixIcon,//出現(xiàn)在文本可編輯部分后,或者裝飾容中文本的后綴上,類型是Widget
this.suffix,//可選小部件,可放置在輸入后的行上。類型是Widget
this.suffixText,//String類型,可選文本后綴,放在輸入后的行上。
this.suffixStyle,//suffixText的樣式,類型為T(mén)extStyle
this.counter,//可選的自定義計(jì)數(shù)器小部件,類型是Widget
this.counterText,//String類型,可選文本放在行下作為字符計(jì)數(shù)。
this.counterStyle,//counterText的樣式,類型TextStyle
this.filled,//bool類型,裝飾的容器將填滿
this.fillColor,//填充顏色,類型是 Color
this.focusColor,//與[fillColor]混合并填充裝飾容器的顏色,類型是 Color
this.hoverColor,//如果容器被鼠標(biāo)懸停在上面,則顯示用于裝飾的焦點(diǎn)突出顯示的顏色。類型是 Color
this.errorBorder,//當(dāng)[InputDecorator]沒(méi)有焦點(diǎn)并且顯示錯(cuò)誤時(shí)要顯示的邊框。類型 InputBorder
this.focusedBorder,//當(dāng)[InputDecorator]有焦點(diǎn)且沒(méi)有顯示錯(cuò)誤時(shí)要顯示的邊框。類型 InputBorder
this.focusedErrorBorder,//當(dāng)[InputDecorator]具有焦點(diǎn)并顯示錯(cuò)誤時(shí)要顯示的邊框。類型 InputBorder
this.disabledBorder,//當(dāng)[InputDecorator]被禁用并且沒(méi)有顯示錯(cuò)誤時(shí)顯示的邊框。類型 InputBorder
this.enabledBorder,//啟用[InputDecorator]時(shí)要顯示的邊框,并且沒(méi)有顯示錯(cuò)誤。類型 InputBorder
this.border,//邊框的形狀,以畫(huà)出周?chē)b飾的容器。類型 InputBorder
this.enabled = true,//bool 類型,如果為false, [helperText]、[errorText]和[counterText]則不展示,其余可視元素的不透明度減少。
this.semanticCounterText,//String類型,對(duì)應(yīng)文本的語(yǔ)義標(biāo)簽。
this.alignLabelWithHint,//bool 類型,當(dāng)[InputDecorator]包含多行時(shí),通常設(shè)置為true
}) : 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.'),
isCollapsed = false;
- TextInputType
| TextInputType的值 | 含義 |
|---|---|
| TextInputType.text | 文本輸入鍵盤(pán) |
| TextInputType.multiline | 多行文本,需和maxLines配合使用(設(shè)為null或大于1) |
| TextInputType.number | 數(shù)字;會(huì)彈出數(shù)字鍵盤(pán) |
| TextInputType.phone | 優(yōu)化后的電話號(hào)碼輸入鍵盤(pán);會(huì)彈出數(shù)字鍵盤(pán)并顯示"* #" |
| TextInputType.datetime | 優(yōu)化后的日期輸入鍵盤(pán);Android上會(huì)顯示“: -” |
| TextInputType.emailAddress | 優(yōu)化后的電子郵件地址;會(huì)顯示“@ .” |
| TextInputType.url | 優(yōu)化后的url輸入鍵盤(pán); 會(huì)顯示“/ .” |
- TextInputAction
類型為T(mén)extInputAction,鍵盤(pán)動(dòng)作按鈕圖標(biāo)(即回車(chē)鍵位圖標(biāo))。
就是鍵盤(pán)右下角的那一個(gè)塊圖標(biāo)。
使用方式
TextField(
textInputAction: TextInputAction.search,
))
效果如下

| TextInputAction的值 | 含義 | 示例 |
|---|---|---|
| TextInputAction.none | Android適用,IOS不適用,表示沒(méi)有相關(guān)的輸入操作 | ![]() |
| TextInputAction.unspecified | 讓系統(tǒng)決定哪個(gè)最合適 | ![]() |
| TextInputAction.done | 用戶完成輸入后,終結(jié)該行為 | ![]() |
| TextInputAction.go | 將用戶帶到程序中與目的地對(duì)應(yīng)的部分,如用戶輸入一個(gè)餐館名稱,點(diǎn)擊后可進(jìn)行導(dǎo)航或者展示目的地位置 | ![]() |
| TextInputAction.search | 執(zhí)行搜索查詢 | ![]() 20190803210756.jpg
|
| TextInputAction.send | 發(fā)送用戶已編寫(xiě)的內(nèi)容,如短信或郵件 | ![]() |
| TextInputAction.next | 用戶已經(jīng)完成當(dāng)前的輸入源,轉(zhuǎn)向下一個(gè) | ![]() |
| TextInputAction.previous | Android上適用,一個(gè)向左的箭頭,表示向后移動(dòng),iOS不適用 | ![]() |
| TextInputAction.continueAction | iOS上使用,Android上不適用,表示繼續(xù)操作 | ![]() |
| TextInputAction.join | 用戶想要加入一些東西,如無(wú)線網(wǎng)絡(luò) | ![]() |
| TextInputAction.route | 用戶需要路由選項(xiàng),如駕駛方向 | ![]() |
| TextInputAction.emergencyCall | 撥打緊急服務(wù)電話 | ![]() |
| TextInputAction.newline | 插入換行符 | ![]() |
- TextCapitalization
| TextCapitalization的值 | 含義 |
|---|---|
| TextCapitalization.none | 全部小寫(xiě) |
| TextCapitalization.words | 每個(gè)單詞的首字母大寫(xiě) |
| TextCapitalization.sentences | 每個(gè)句子的首字母大寫(xiě) |
| TextCapitalization.characters | 每個(gè)字每大寫(xiě) |
- Brightness
| Brightness的值 | 含義 |
|---|---|
| Brightness.dark | 深色主題 |
| Brightness.light | 淺色主題 |
- DragStartBehavior
| DragStartBehavior的值 | 含義 |
|---|---|
| DragStartBehavior.down | 在檢測(cè)到第一個(gè)down事件的位置設(shè)置初始偏移量。 |
| DragStartBehavior.start | 將初始位置設(shè)置為檢測(cè)到拖動(dòng)啟動(dòng)事件的位置。 |
結(jié)尾
截止到這里TextField就介紹完了。
以下是我的Flutter系列的鏈接,后續(xù)會(huì)持續(xù)更新,歡迎大家指正。
Flutter 系列文章
- Flutter 學(xué)習(xí) - 開(kāi)篇
- Flutter 學(xué)習(xí) - 基礎(chǔ)框架
- Flutter 學(xué)習(xí) - 網(wǎng)絡(luò)請(qǐng)求和數(shù)據(jù)解析
- Flutter 學(xué)習(xí) - Widget 之 Text
- Flutter 學(xué)習(xí) - Widget 之 RichText
- Flutter 學(xué)習(xí) - Widget 之 Image和Icon
- Flutter 學(xué)習(xí) - Widget 之 TextField
- Flutter 學(xué)習(xí) - Widget 之 對(duì)話框
- Flutter 學(xué)習(xí) - Widget 之 菜單按鈕
- Flutter 學(xué)習(xí) - Widget 之 布局 Widget
- Flutter 學(xué)習(xí) - 容器類Widget
- Flutter 學(xué)習(xí) - 可滾動(dòng)的 Widget
- Flutter 學(xué)習(xí) - 功能類Widget












