Material組件庫中提供了輸入框組件TextField和表單組件Form各谚。下面我們分別介紹一下迄薄。
- 組件 - TextField
- 表單Form
1. 組件 - TextField
TextField用于文本輸入
屬性包括:
controller:編輯框的控制器凝颇,通過它可以設(shè)置/獲取編輯框的內(nèi)容、選擇編輯內(nèi)容叽讳、監(jiān)聽編輯文本改變事件拟蜻。大多數(shù)情況下我們都需要顯式提供一個controller來與文本框交互。如果沒有提供controller震捣,則TextField內(nèi)部會自動創(chuàng)建一個荔棉。
focusNode:用于控制TextField是否占有當前鍵盤的輸入焦點闹炉。它是我們和鍵盤交互的一個句柄 (handle)。
InputDecoration:用于控制TextField的外觀顯示润樱,如提示文本渣触、背景顏色、邊框等壹若。
- labelText: "用戶名",
- hintText: "用戶名或郵箱",
- prefixIcon: Icon(Icons.person)
- // 未獲得焦點下劃線設(shè)為灰色
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.grey),
),
- //獲得焦點下劃線設(shè)為藍色
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue),
),
- keyboardType:用于設(shè)置該輸入框默認的鍵盤輸入類型嗅钻,取值如下:
- text 文本輸入鍵盤
- multiline 多行文本,需和maxLines配合使用(設(shè)為null或大于1)
- number 數(shù)字店展;會彈出數(shù)字鍵盤
- phone 優(yōu)化后的電話號碼輸入鍵盤养篓;會彈出數(shù)字鍵盤并顯示“* #”
- datetime 優(yōu)化后的日期輸入鍵盤;Android上會顯示“: -”
- emailAddress 優(yōu)化后的電子郵件地址赂蕴;會顯示“@ .”
- url 優(yōu)化后的url輸入鍵盤柳弄; 會顯示“/ .”
textInputAction:鍵盤動作按鈕圖標(即回車鍵位圖標)
style:正在編輯的文本樣式。
textAlign: 輸入框內(nèi)編輯文本在水平方向的對齊方式概说。
autofocus: 是否自動獲取焦點碧注。
obscureText:是否隱藏正在編輯的文本,如用于輸入密碼的場景等糖赔,文本內(nèi)容會用“?”替換萍丐。
maxLines:輸入框的最大行數(shù),默認為1放典;如果為null逝变,則無行數(shù)限制。
maxLength和maxLengthEnforced :maxLength代表輸入框文本的最大長度奋构,設(shè)置后輸入框右下角會顯示輸入的文本計數(shù)骨田。
maxLengthEnforced決定當輸入文本長度超過maxLength時是否阻止輸入,為true時會阻止輸入声怔,為false時不會阻止輸入但輸入框會變紅态贤。onChange:輸入框內(nèi)容改變時的回調(diào)函數(shù);注:內(nèi)容改變事件也可以通過controller來監(jiān)聽醋火。
onEditingComplete和onSubmitted:這兩個回調(diào)都是在輸入框輸入完成時觸發(fā)悠汽,比如按了鍵盤的完成鍵(對號圖標)或搜索鍵(??圖標)。不同的是兩個回調(diào)簽名不同芥驳,onSubmitted回調(diào)是ValueChanged<String>類型柿冲,它接收當前輸入內(nèi)容做為參數(shù),而onEditingComplete不接收參數(shù)兆旬。
inputFormatters:用于指定輸入格式假抄;當用戶輸入內(nèi)容改變時,會根據(jù)指定的格式來校驗。
enable:如果為false宿饱,則輸入框會被禁用熏瞄,禁用狀態(tài)不接收輸入和事件,同時顯示禁用態(tài)樣式(在其- decoration中定義)谬以。
cursorWidth强饮、cursorRadius和cursorColor:這三個屬性是用于自定義輸入框光標寬度、圓角和顏色的为黎。
當獲取一個文本框輸入的值時邮丰,代碼示例
// 定一個controller
TextEditingController _textController= TextEditingController();
TextField(
autofocus: true,
controller: _textController, //設(shè)置controller
...
)
// 獲取輸入框內(nèi)容
_textController.text
2. 表單Form
Flutter提供了一個Form 組件,它可以對輸入框進行分組铭乾,然后進行一些統(tǒng)一操作剪廉,如輸入內(nèi)容校驗、輸入框重置以及輸入內(nèi)容保存炕檩。
Form繼承自StatefulWidget對象妈经,它對應(yīng)的狀態(tài)類為FormState。我們先看看Form類的定義:
Form({
Key key,
@required this.child,
this.autovalidate = false,
this.onWillPop,
this.onChanged,
})
key: 通過key屬性捧书,來獲取表單對象。
child: 是表單里的一些布局骤星,結(jié)合TextFormField組件來實現(xiàn)表單的驗證经瓷。
autovalidate:是否自動校驗輸入內(nèi)容;當為true時洞难,每一個子FormField內(nèi)容發(fā)生變化時都會自動校驗合法性舆吮,并直接顯示錯誤信息。否則队贱,需要通過調(diào)用FormState.validate()來手動校驗色冀。
onWillPop:決定Form所在的路由是否可以直接返回(如點擊返回按鈕),該回調(diào)返回一個Future對象柱嫌,如果Future的最終結(jié)果是false锋恬,則當前路由不會返回;如果為true编丘,則會返回到上一個路由与学。此屬性通常用于攔截返回按鈕。
onChanged:Form的任意一個子FormField內(nèi)容發(fā)生變化時會觸發(fā)此回調(diào)嘉抓。
示例代碼如下:
class FormTest extends StatefulWidget {
@override
_FormTestState createState() => new _FormTestState();
}
class _FormTestState extends State<FormTest> {
TextEditingController _unameController = new TextEditingController();
TextEditingController _pwdController = new TextEditingController();
GlobalKey _formKey= new GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title:Text("Form Test"),
),
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
child: Form(
key: _formKey, //設(shè)置globalKey索守,用于后面獲取FormState
autovalidate: true, //開啟自動校驗
child: Column(
children: <Widget>[
TextFormField(
autofocus: true,
controller: _unameController,
decoration: InputDecoration(
labelText: "用戶名",
hintText: "用戶名或郵箱",
icon: Icon(Icons.person)
),
// 校驗用戶名
validator: (v) {
return v.trim().length > 0 ? null : "用戶名不能為空";
}
),
TextFormField(
controller: _pwdController,
decoration: InputDecoration(
labelText: "密碼",
hintText: "您的登錄密碼",
icon: Icon(Icons.lock)
),
obscureText: true,
//校驗密碼
validator: (v) {
return v.trim().length > 5 ? null : "密碼不能少于6位";
}
),
// 登錄按鈕
Padding(
padding: const EdgeInsets.only(top: 28.0),
child: Row(
children: <Widget>[
Expanded(
child: RaisedButton(
padding: EdgeInsets.all(15.0),
child: Text("登錄"),
color: Theme.of(context).primaryColor,
textColor: Colors.white,
onPressed: () {
// 通過_formKey.currentState 獲取FormState后,
// 調(diào)用validate()方法校驗用戶名密碼是否合法抑片,校驗
// 通過后再提交數(shù)據(jù)卵佛。
if((_formKey.currentState as FormState).validate()){
//驗證通過提交數(shù)據(jù)
}
},
),
),
],
),
)
],
),
),
),
);
}
}
還可以通過Form.of(context)來驗證表單提交,如果直接在 onPressed 方法中獲取,是不可行的截汪,因為獲取到的上下文context為 FormTest的context疾牲,而FormState是在FormTest的子樹中, 所以需要通過Builder來構(gòu)建按鈕挫鸽,Builder會將widget節(jié)點的context作為回調(diào)參數(shù)说敏,代碼示例如下:
Expanded(
child:Builder(builder: (context){
return RaisedButton(
onPressed: () {
if(Form.of(context).validate()){
//驗證通過提交數(shù)據(jù)
}
},
);
})
)