這是我參與8月更文挑戰的第7天,活動詳情檢視:8月更文挑戰
TextField
顧名思義文字輸入框,類似於iOS中的UITextField和Android中的EditText和Web中的TextInput。主要是為使用者提供輸入文字提供方便。相信大家在原生客戶端上都用過這個功能,就不在做具體介紹了,接下來還是具體介紹下Flutter中TextField的用法。
以下內容已更新到 github
TextField的構造方法:
const TextField({
Key key,
this.controller, //控制器,控制TextField文字
this.focusNode,
this.decoration: const InputDecoration(), //輸入器裝飾
TextInputType keyboardType: TextInputType.text, //輸入的型別
this.style,
this.textAlign: TextAlign.start,
this.autofocus: false,
this.obscureText: false, //是否隱藏輸入
this.autocorrect: true,
this.maxLines: 1,
this.maxLength,
this.maxLengthEnforced: true,
this.onChanged, //文字改變觸發
this.onSubmitted, //文字提交觸發(鍵盤按鍵)
this.onEditingComplete, //當使用者提交可編輯內容時呼叫
this.inputFormatters,
this.enabled,
this.cursorWidth = 2.0,
this.cursorRadius,
this.cursorColor,
this.keyboardAppearance,
})
複製程式碼
先來試試最基本的TextField:
/*
* Created by 李卓原 on 2018/9/7.
* email: zhuoyuan93@gmail.com
*
*/
import 'package:flutter/material.dart';
class TextFieldAndCheckPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => TextFieldAndCheckPageState();
}
class TextFieldAndCheckPageState extends State<TextFieldAndCheckPage> {
@override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(
title: Text('輸入和選擇'),
),body:TextField(),
);
}
}
複製程式碼
這是一個預設的輸入框,我們什麼都沒有做的時候的樣子. 然後我們試一下它的屬性
TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
icon: Icon(Icons.text_fields),
labelText: '請輸入你的姓名)',
helperText: '請輸入你的真實姓名',
),
onChanged: _textFieldChanged,
autofocus: false,
),
void _textFieldChanged(String str) {
print(str);
}
複製程式碼
我們增加一個keyboardType屬性,把keyboardType設定為TextInputType.number 可以看到每次我們讓TextField獲得焦點的時候彈出的鍵盤就變成了數字優先了。 然後我們為輸入框做一些其他的效果,如提示文字,icon、標籤文字等。 我們給上面的程式碼新增decoration屬性,設定相關屬性,可以發現當我們的TextField獲得焦點時,圖示會自動變色,提示文字會自動上移。
還可以看到 我加了一個onChanged
。
onChanged
是每次輸入框內每次文字變更觸發的回撥,onSubmitted
是使用者提交而觸發的回撥。
每當使用者改變輸入框內的文字,都會在控制檯輸出現在的字串.與onSubmitted
用法相同.
接下來,我們實現一個簡單的登入頁面:
/*
* Created by 李卓原 on 2018/9/7.
* email: zhuoyuan93@gmail.com
*
*/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class TextFieldAndCheckPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => TextFieldAndCheckPageState();
}
class TextFieldAndCheckPageState extends State<TextFieldAndCheckPage> {
//手機號的控制器
TextEditingController phoneController = TextEditingController();
//密碼的控制器
TextEditingController passController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('輸入和選擇'),
),
body: Column(
children: <Widget>[
TextField(
controller: phoneController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
icon: Icon(Icons.phone),
labelText: '請輸入你的使用者名稱)',
helperText: '請輸入註冊的手機號',
),
autofocus: false,
),
TextField(
controller: passController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
icon: Icon(Icons.lock),
labelText: '請輸入密碼)',
),
obscureText: true),
RaisedButton(
onPressed: _login,
child: Text('登入'),
),
],
),
);
}
void _login() {
print({'phone': phoneController.text, 'password': passController.text});
if (phoneController.text.length != 11) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('手機號碼格式不對'),
));
} else if (passController.text.length == 0) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('請填寫密碼'),
));
} else {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('登入成功'),
));
phoneController.clear();
}
}
void onTextClear() {
setState(() {
phoneController.clear();
passController.clear();
});
}
}
複製程式碼
在佈局上,我們使用一個Column包含了兩個TextField和一個RaisedButton。 在邏輯上,每當我們點選下面的按鈕都會判斷使用者名稱密碼是否符合要求,並且使用控制器清空已經輸入的使用者名稱和密碼。
當使用者輸入的手機號碼不是11位的時候提示手機號碼格式錯誤, 當使用者沒有輸入密碼時,提示填寫密碼, 使用者名稱和密碼符合要求時提示登入成功。
我這裡登入成功之後還調了一個方法:phoneController.clear()
清空了使用者名稱輸入框中的內容。
程式碼的邏輯很簡單。關於TextField的其他用法就不在一一介紹了,有興趣的小夥伴可以自己嘗試下.
使用decoration美化輸入框
先看一下效果:
程式碼:
TextField(
controller: accountController,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: '請輸入賬號',
labelText: '左上角',
prefixIcon: Icon(Icons.person),
),
)
複製程式碼
可以看到,我先新增了一個decoration屬性.
decoration屬性介紹:
border:增加一個邊框, hintText:未輸入文字時,輸入框中的提示文字, prefixIcon:輸入框內側左面的控制元件, labelText:一個提示文字。輸入框獲取焦點/輸入框有內容 會移動到左上角,否則在輸入框內,labelTex的位置. suffixIcon: 輸入框內側右面的圖示. icon : 輸入框左側新增個圖示
在多個輸入框內切換焦點
介紹一下onEditingComplete
這個方法:
當使用者提交可編輯內容時呼叫(例如,使用者按下鍵盤上的“done”按鈕)。
onEditingComplete
的預設實現根據情況執行2種不同的行為:
- 當完成操作被按下時,例如“done”、“go”、“send”或“search”,使用者的內容被提交給[controller],然後焦點被放棄。
- 當按下一個未完成操作(如“next”或“previous”)時,使用者的內容被提交給[controller],但不會放棄焦點,因為開發人員可能希望立即將焦點轉移到[onsubmit]中的另一個輸入小部件。
我們有時候會需要這樣的情況, 比如一個登入頁面, 需要輸入賬號和密碼 , 自然輸入完賬號就要輸入密碼了 , 我們在輸入賬號結束的時候 , 讓密碼輸入框獲取到焦點 .
看一下程式碼:
...
FocusNode secondTextFieldNode = FocusNode();
...
Column(
children: <Widget>[
TextField(
/* onChanged: (text) {
value = text;
print(value);
},*/
autofocus: false, //是否自動獲取焦點
controller: _textController,
decoration: InputDecoration(
suffixIcon: Icon(Icons.chevron_right), //輸入框內右側圖示
icon: Icon(Icons.person), //輸入框左側圖示
prefixIcon: Icon(Icons.skip_previous), //輸入框內左側圖示
labelText: 'labelText',
hintText: 'hintText',
helperText: 'helperText',
),
onEditingComplete: () =>
FocusScope.of(context).requestFocus(secondTextFieldNode),
),
TextField(
focusNode: secondTextFieldNode,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 15.0)),
),
],
),
複製程式碼
我在頂層建立了一個交電接點並附加給第二個輸入框,
在第一個輸入框的onEditingComplete
方法中是用
FocusScope.of(context).requestFocus(secondTextFieldNode),
複製程式碼
方法來讓第二個輸入框請求獲取焦點, 當然你也可以新增個按鈕 , 點選按鈕執行這個方法來實現切換焦點的功能.
例如: [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-BjSYHYmc-1573730655449)(cdn-images-1.medium.com/max/800/1*v…)] 程式碼很簡單,我就不貼了.
keyboardType
TextField成為焦點時顯示的鍵盤型別。
TextField(
keyboardType: TextInputType.number,
),
複製程式碼
型別是:
- TextInputType.text(普通完整鍵盤)
- TextInputType.number(數字鍵盤)
- TextInputType.emailAddress(帶有“@”的普通鍵盤)
- TextInputType.datetime(帶有“/”和“:”的數字鍵盤)
- TextInputType.multiline(帶有選項以啟用有符號和十進位制模式的數字鍵盤)
TextInputAction
更改TextField的textInputAction可以更改鍵盤本身的操作按鈕。
TextField(
textInputAction: TextInputAction.search,
),
複製程式碼
這會導致“完成”按鈕被“搜尋”按鈕替換:
TextCapitalization
TextField提供了一些有關如何使使用者輸入中的字母大寫的選項。
- TextCapitalization.sentences : 這是我們期望的正常型別的大寫,每個句子的首字母大寫。
- TextCapitalization.characters:大寫句子中的所有字元。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-4ykAhgu0-1573730655451)(cdn-images-1.medium.com/max/800/1*S…)]
- TextCapitalization.words : 將每個單詞的首字母大寫。
更改TextField中的游標
可以直接從TextField小部件自定義遊標。
可以更改角落的游標顏色,寬度和半徑。 例如,這裡我沒有明顯的原因製作一個圓形的紅色游標。
TextField(
cursorColor: Colors.red,
cursorRadius: Radius.circular(16.0),
cursorWidth: 16.0,
),
複製程式碼
控制TextField中的大小和最大長度
TextFields可以控制在其中寫入的最大字元數,最大行數並在鍵入文字時展開。
TextField(
maxLength: 4,
),
複製程式碼
通過設定maxLength屬性,將強制執行最大長度,並且預設情況下會將計數器新增到TextField。