Flutter關於TextField你能知道的一切

蘇武難飛發表於2019-07-15

前言

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元件包裹才能使用,我們可以用CardDialog,Drawer,Scaffold,甚至直接用Material。但是我們不需要直接包裹住,只要TextField渲染時向上查詢可以找到Material元件就ok。

01

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

02
小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

  1. obscureText用來隱藏輸入內容,一般輸入密碼時需要設定這個屬性。
  2. autofocus用來設定是否自動獲取焦點,預設為false。注意:設定focusNode後此屬性失效。
  3. focusNode用來控制TextField焦點,也可控制軟鍵盤彈出隱藏~
    03
    04
    如果一個頁面有多個TextField還可以用focusNode來控制具體哪一個TextField獲取焦點
    05
    focusNode還可以獲取焦點狀態~
FocusNode focusNode = FocusNode();
focusNode.addListener(() {
      if (focusNode.hasFocus)
        print('獲得焦點');
      else
        print('失去焦點');
});
複製程式碼

cursorWidth/cursorRadius/cursorColor

06

  • 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點選軟鍵盤確認按鈕的回撥 注意這裡的確認可以是donesearchgo
 TextField(   
     onSubmitted: (value) {
        print('value:' + value);
})
I/flutter (14978): value:蘇武難飛
I/flutter (14978): value:蘇武難飛
複製程式碼

還需要注意的一點就是單獨註冊onSubmitted時點選後會關閉軟鍵盤~

  • onEditingComplete 點選軟鍵盤確認按鈕的回撥? 這個方法和上面的onSubmitted區別在於
  1. 沒有value回撥
  2. 點選後不會關閉軟鍵盤 適用場景例如:當前頁面有兩個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用來設定軟鍵盤圖示可以設定為SearchNextgoprevious等等,需要注意的是部分InputAction可能只有Android平臺有,部分InputAction可能只有iOS平臺有。
  • textCapitalization用來控制使用者輸入文字大小寫
    07
  • textAlign文字對齊方式 這個其實很好理解,就像原生Android中的Gravity,本章節就拿center舉一個小例子。
    08
  • textDirection控制文字方向

style/decoration

  • style

逐漸到了重頭戲了嗷~,style用來控制輸入文字樣式舉個栗子

09

  • decoration用來控制輸入框樣式 我們先來做一個非常Material Design的輸入框~
 TextField(
    decoration: InputDecoration(labelText: 'Name')
)
複製程式碼

10
InputDecoration功能是非常豐富的,我們還可以新增border屬性來讓我們輸入框更加有Material感覺。

border

  • OutlineInputBorder
TextField(
   decoration: InputDecoration(labelText: 'Name',border:OutlineInputBorder())
)
複製程式碼

11

wow~奧搜!不喜歡花裡胡哨就想要個圓角?沒問題~
 TextField(
    decoration: InputDecoration(hintText: 'Name',border: OutlineInputBorder(borderRadius:BorderRadius.all(Radius.circular(16.0)))))
複製程式碼

12

想要更改邊框顏色?簡單~有兩種方式可以辦到
  1. 通過屬性更改
  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))))
複製程式碼

13
注意:單獨更改border是不生效的,會被enabledBorderfocusedBorder所覆蓋。

  1. 通過Theme更改
Theme(
   data: ThemeData(primaryColor: Colors.red),
   child: TextField(
       decoration: InputDecoration(
           labelText: 'Name', border: OutlineInputBorder())),
)
複製程式碼

13

還要更改邊框粗細?撒撒水啦~
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))))
複製程式碼

14

  • UnderlineInputBorder

表現形式與預設的樣式相同,更改顏色和圓角粗細也與OutlineInputBorder一致~

Icon/prefixIcon/suffixIcon

15
小tip:suffixIcon可以用來做清空輸入框的×

suffixText/labelText/counterText/errorText/helperText/prefixText/hintText

16
小tip:errorTexthelperText都有內容時,只有errorText會生效

filled/fillColor

17

maxLines

Flutter中的TextField預設表現輸入形式是單行輸入,如果我們設定了maxLines呢?請看圖?~

18
我們設定了maxLines之後整體的高度都被放大了,這顯然不是我們想要的效果,我們想要的應該是輸入超出一行後會自動換行,像原生AndroidEditText一樣,怎麼做呢,其實也很簡單,看圖┗|`O′|┛ 嗷~~
19

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個贊吧?

相關文章