前言
Hello,大家好這裡是一個苦逼的前Android
開發,本來Android
乾的開開心心,但是受到一些影響轉行了?,不過我就是吃不起飯,找不到工作也不會放棄Android
開發!,Flutter
真香!!我個人自學Flutter
以來受到了諸多大佬文章的啟迪,所以也萌生了寫一下分享文章給同樣需要幫助的同學們。
TextField 文字輸入框
TextField
文字輸入框相信大家都不陌生,本篇文章帶你更加仔細的學習TextField
的一切。
建議閱讀時間: 沒事可以多來看看啊?
如何使用TextField
Widget build(BuildContext context) {
return Container(child: TextField());
}
複製程式碼
大功告成?naive,這段程式碼收穫的是一段報錯,提煉之後的報錯資訊
I/flutter ( 7877): No Material widget found.`
I/flutter ( 7877): TextField widgets require a Material widget ancestor.
I/flutter ( 7877): Material itself, such as a Card, Dialog, Drawer, or Scaffold.
複製程式碼
這個錯誤很好解決,TextField
需要被Material
元件包裹才能使用,我們可以用Card
,Dialog
,Drawer
,Scaffold
,甚至直接用Material
。但是我們不需要直接包裹住,只要TextField
渲染時向上查詢可以找到Material
元件就ok。
TextField可選引數
const TextField({
Key key,
this.controller,
this.focusNode,
this.decoration = const InputDecoration(),
TextInputType keyboardType,
this.textInputAction,
this.textCapitalization = TextCapitalization.none,
this.style,
this.textAlign = TextAlign.start,
this.textDirection,
this.autofocus = false,
this.obscureText = false,
this.autocorrect = true,
this.maxLines = 1,
this.maxLength,
this.maxLengthEnforced = true,
this.onChanged,
this.onEditingComplete,
this.onSubmitted,
this.inputFormatters,
this.enabled,
this.cursorWidth = 2.0,
this.cursorRadius,
this.cursorColor,
this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.down,
this.enableInteractiveSelection,
this.onTap,
this.buildCounter,
})
複製程式碼
maxLength/maxLengthEnforced/inputFormatters
小tip:如果想要限制字數,同時不想要右下角的計數標記可以使用inputFormatters
inputFormatters: [LengthLimitingTextInputFormatter(20)]
複製程式碼
inputFormatters
用來限制輸入內容,我們可以自定義一個只接受輸入數字內容的inputFormatters
class NumberFormatter extends TextInputFormatter {
bool isNumber(String value) {
return RegExp('^[0-9]*\$').hasMatch(value);
}
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
String value = newValue.text;
return isNumber(value) ? newValue : oldValue;
}
}
複製程式碼
obscureText/autofocus/focusNode
obscureText
用來隱藏輸入內容,一般輸入密碼時需要設定這個屬性。autofocus
用來設定是否自動獲取焦點,預設為false
。注意:設定focusNode
後此屬性失效。focusNode
用來控制TextField
焦點,也可控制軟鍵盤彈出隱藏~ 如果一個頁面有多個TextField
還可以用focusNode
來控制具體哪一個TextField
獲取焦點focusNode
還可以獲取焦點狀態~
FocusNode focusNode = FocusNode();
focusNode.addListener(() {
if (focusNode.hasFocus)
print('獲得焦點');
else
print('失去焦點');
});
複製程式碼
cursorWidth/cursorRadius/cursorColor
cursorWidth
設定游標寬度cursorRadius
設定游標圓角cursorColor
設定游標顏色
enabled/enableInteractiveSelection
enabled
是否禁用輸入框enableInteractiveSelection
值為true
時可以長按選擇複製貼上,false
時禁用。
onTap/onSubmitted/onEditingComplete
onTap
單擊輸入框的回撥
TextField(
onTap: () {
print('onTap()');
}
//單擊時
I/flutter (14649): onTap()
I/flutter (14649): onTap()
複製程式碼
onSubmitted
點選軟鍵盤確認按鈕的回撥 注意這裡的確認可以是done
、search
、go
等
TextField(
onSubmitted: (value) {
print('value:' + value);
})
I/flutter (14978): value:蘇武難飛
I/flutter (14978): value:蘇武難飛
複製程式碼
還需要注意的一點就是單獨註冊onSubmitted
時點選後會關閉軟鍵盤~
onEditingComplete
點選軟鍵盤確認按鈕的回撥? 這個方法和上面的onSubmitted
區別在於
- 沒有
value
回撥 - 點選後不會關閉軟鍵盤
適用場景例如:當前頁面有兩個
TextField
一個負責使用者名稱一個負責密碼,使用者輸入完使用者名稱後可以很自然的點選軟鍵盤的按鈕使焦點聚焦於密碼框。
TextField(
onEditingComplete: () {
print('onEditingComplete()');
FocusScope.of(context).requestFocus(focusNode);
},
textInputAction: TextInputAction.next),
TextField(focusNode: focusNode)
I/flutter (15170): onEditingComplete()
I/flutter (15170): onEditingComplete()
複製程式碼
textInputAction/textCapitalization/textAlign/textDirection
textInputAction
用來設定軟鍵盤圖示可以設定為Search
、Next
、go
、previous
等等,需要注意的是部分InputAction
可能只有Android
平臺有,部分InputAction
可能只有iOS
平臺有。textCapitalization
用來控制使用者輸入文字大小寫textAlign
文字對齊方式 這個其實很好理解,就像原生Android
中的Gravity
,本章節就拿center
舉一個小例子。textDirection
控制文字方向
style/decoration
style
逐漸到了重頭戲了嗷~,style
用來控制輸入文字樣式舉個栗子
decoration
用來控制輸入框樣式 我們先來做一個非常Material Design
的輸入框~
TextField(
decoration: InputDecoration(labelText: 'Name')
)
複製程式碼
InputDecoration
功能是非常豐富的,我們還可以新增border
屬性來讓我們輸入框更加有Material
感覺。
border
OutlineInputBorder
TextField(
decoration: InputDecoration(labelText: 'Name',border:OutlineInputBorder())
)
複製程式碼
wow~奧搜!不喜歡花裡胡哨就想要個圓角?沒問題~
TextField(
decoration: InputDecoration(hintText: 'Name',border: OutlineInputBorder(borderRadius:BorderRadius.all(Radius.circular(16.0)))))
複製程式碼
想要更改邊框顏色?簡單~有兩種方式可以辦到
- 通過屬性更改
TextField(
decoration: InputDecoration(
labelText: 'Name',
labelStyle: TextStyle(color: Colors.red),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color:Colors.red)),
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color:Colors.red))))
複製程式碼
注意:單獨更改border
是不生效的,會被enabledBorder
和focusedBorder
所覆蓋。
- 通過
Theme
更改
Theme(
data: ThemeData(primaryColor: Colors.red),
child: TextField(
decoration: InputDecoration(
labelText: 'Name', border: OutlineInputBorder())),
)
複製程式碼
還要更改邊框粗細?撒撒水啦~
TextField(
decoration: InputDecoration(
labelText: 'Name',
labelStyle: TextStyle(color: Colors.red),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Colors.red, width: 3.0)),
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Colors.red, width: 3.0))))
複製程式碼
UnderlineInputBorder
表現形式與預設的樣式相同,更改顏色和圓角粗細也與OutlineInputBorder
一致~
Icon/prefixIcon/suffixIcon
小tip:suffixIcon
可以用來做清空輸入框的×
suffixText/labelText/counterText/errorText/helperText/prefixText/hintText
小tip:errorText
與helperText
都有內容時,只有errorText
會生效
filled/fillColor
maxLines
Flutter
中的TextField
預設表現輸入形式是單行輸入,如果我們設定了maxLines
呢?請看圖?~
maxLines
之後整體的高度都被放大了,這顯然不是我們想要的效果,我們想要的應該是輸入超出一行後會自動換行,像原生Android
的EditText
一樣,怎麼做呢,其實也很簡單,看圖┗|`O′|┛ 嗷~~
onChanged/TextEditingController
如何處理文字輸入呢,我們有兩個辦法。
onChanged
回撥
每當使用者輸入時,TextField會呼叫它的onChanged回撥。 您可以處理此回撥以檢視使用者輸入的內容。例如,如果您正在輸入搜尋欄位,則可能需要在使用者輸入時更新搜尋結果。
TextField(onChanged: (value) {
print('value: ${value}');
}
I/flutter (23802): value:蘇
I/flutter (23802): value:蘇武
I/flutter (23802): value:蘇武難
I/flutter (23802): value:蘇武難飛
複製程式碼
一個更強大(但更精細)的方法是提供一個TextEditingController作為TextField的controller屬性。 在使用者輸入時,controller的text和selection屬性不斷的更新。要在這些屬性更改時得到通知,請使用controller的addListener方法監聽控制器 。 (如果你新增了一個監聽器,記得在你的State物件的dispose方法中刪除監聽器 )。
TextEditingController _controller = TextEditingController();
_controller.addListener(() {
String text = _controller.text;
int length = text.length;
print('text: ${text} length:${length}');
if (length >= 5) {
_controller.clear();
}
});
I/flutter (23802): text: 蘇 length:1
I/flutter (23802): text: 蘇武難飛 length:4
I/flutter (23802): text: 蘇武難飛帥 length:5
I/flutter (23802): text: length:0
複製程式碼
後記
本篇內容到這裡就結束了,雖然我不再做Android
開發,但是我卻依然喜愛懷念做開發的日子。給自己定個小目標,希望下半年可以在掘金社群有50個贊吧?