Flutter文本輸入框TextField屬性(InputDecoration、textInputAction、inputFormatters等等)詳解


 

TextField

Flutter中的文本輸入框(TextField)就類似於Android中的EditText,但是用起來比EditText方便很多,改變樣式也更加的方便。下面我們來看一下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,  //配合maxLength一起使用,在達到最大長度時是否阻止輸入
    this.onChanged,  //輸入文本發生變化時的回調
    this.onEditingComplete,   //點擊鍵盤完成按鈕時觸發的回調,該回調沒有參數,(){}
    this.onSubmitted,  //同樣是點擊鍵盤完成按鈕時觸發的回調,該回調有參數,參數即為當前輸入框中的值。(String){}
    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,
  })

可以看到,屬性還是很多的,但都比較簡單,下面我們來看一下常用的屬性。


TextField decoration

我們首先來看一下decoration
decoration(裝飾器) 接收一個InputDecoration類型的值,主要用於控制TextField的外觀以及提示信息等
我們來看看InputDecoration的構造方法

InputDecoration({
    this.icon,    //位於裝飾器外部和輸入框前面的圖片
    this.labelText,  //用於描述輸入框,例如這個輸入框是用來輸入用戶名還是密碼的,當輸入框獲取焦點時默認會浮動到上方,
    this.labelStyle,  // 控制labelText的樣式,接收一個TextStyle類型的值
    this.helperText, //輔助文本,位於輸入框下方,如果errorText不為空的話,則helperText不會顯示
    this.helperStyle, //helperText的樣式
    this.hintText,  //提示文本,位於輸入框內部
    this.hintStyle, //hintText的樣式
    this.hintMaxLines, //提示信息最大行數
    this.errorText,  //錯誤信息提示
    this.errorStyle, //errorText的樣式
    this.errorMaxLines,   //errorText最大行數
    this.hasFloatingPlaceholder = true,  //labelText是否浮動,默認為true,修改為false則labelText在輸入框獲取焦點時不會浮動且不顯示
    this.isDense,   //改變輸入框是否為密集型,默認為false,修改為true時,圖標及間距會變小
    this.contentPadding, //內間距
    this.prefixIcon,  //位於輸入框內部起始位置的圖標。
    this.prefix,   //預先填充的Widget,跟prefixText同時只能出現一個
    this.prefixText,  //預填充的文本,例如手機號前面預先加上區號等
    this.prefixStyle,  //prefixText的樣式
    this.suffixIcon, //位於輸入框后面的圖片,例如一般輸入框后面會有個眼睛,控制輸入內容是否明文
    this.suffix,  //位於輸入框尾部的控件,同樣的不能和suffixText同時使用
    this.suffixText,//位於尾部的填充文字
    this.suffixStyle,  //suffixText的樣式
    this.counter,//位於輸入框右下方的小控件,不能和counterText同時使用
    this.counterText,//位於右下方顯示的文本,常用於顯示輸入的字符數量
    this.counterStyle, //counterText的樣式
    this.filled,  //如果為true,則輸入使用fillColor指定的顏色填充
    this.fillColor,  //相當於輸入框的背景顏色
    this.errorBorder,   //errorText不為空,輸入框沒有焦點時要顯示的邊框
    this.focusedBorder,  //輸入框有焦點時的邊框,如果errorText不為空的話,該屬性無效
    this.focusedErrorBorder,  //errorText不為空時,輸入框有焦點時的邊框
    this.disabledBorder,  //輸入框禁用時顯示的邊框,如果errorText不為空的話,該屬性無效
    this.enabledBorder,  //輸入框可用時顯示的邊框,如果errorText不為空的話,該屬性無效
    this.border, //正常情況下的border
    this.enabled = true,  //輸入框是否可用
    this.semanticCounterText,  
    this.alignLabelWithHint,
  })

我們先來用一下InputDecoration,這里我們主要介紹一下常用的屬性
默認樣式

TextField(
      decoration: InputDecoration(),
    );

在這里插入圖片描述

icon

TextField(
      decoration: InputDecoration(
        icon: Icon(Icons.person),
      ),
    );

在這里插入圖片描述

labelText

用於描述輸入框,例如這個輸入框是用來輸入用戶名還是密碼的,當輸入框獲取焦點時默認會浮動到上方

TextField(
      decoration: InputDecoration(
        icon: Icon(Icons.person),
        labelText: "labelText",
      ),
    );


下面輸入框的用戶名對應的就是labelText
在這里插入圖片描述

labelStyle

設置labelText的樣式

TextField(
      decoration: InputDecoration(
          icon: Icon(Icons.person),
          labelText: "labelText",
          labelStyle: TextStyle(
            color: Colors.red,
            fontSize: 20,
          )),
    );


在這里插入圖片描述

helperText

輔助文本,位於輸入框下方,如果errorText不為空的話,則helperText不會顯示

TextField(
      decoration: InputDecoration(
        icon: Icon(Icons.person),
        labelText: "labelText",
        helperText: "helperText",
      ),
    );


在這里插入圖片描述

helperStyle

TextField(
      decoration: InputDecoration(
        icon: Icon(Icons.person),
        labelText: "labelText",
        helperText: "helperText",
        helperStyle: TextStyle(
          color: Colors.green,//綠色
          fontSize: 20,//字體變大
        ),
      ),
    );



在這里插入圖片描述

errorText

錯誤提示信息,如果該屬性不為null的話,labelText失效。

TextField(
      decoration: InputDecoration(
        icon: Icon(Icons.person),
        labelText: "labelText",
        helperText: "helperText",
        errorText: "errorText",
      ),
    );




在這里插入圖片描述

hintText

輸入框中的提示信息,這個沒啥好說的

TextField(
      decoration: InputDecoration(
        icon: Icon(Icons.person),
        hintText: "hintText",
      ),
    );



在這里插入圖片描述

hasFloatingPlaceholder

labelText是否浮動,默認為true,修改為false則labelText在輸入框獲取焦點時不會浮動且不顯示

TextField(
      decoration: InputDecoration(
        icon: Icon(Icons.person),
        hasFloatingPlaceholder: false,
        labelText: "labelText",
        helperText: "helperText",
        errorText: "errorText",
        hintText: "hintText",
      ),
    );


在這里插入圖片描述

prefixIcon、prefixText

圖片和預填充的文字

TextField(
      decoration: InputDecoration(
        icon: Icon(Icons.person),
        hasFloatingPlaceholder: false,
        labelText: "labelText",
        helperText: "helperText",
        errorText: "errorText",
       // hintText: "hintText",
        prefixIcon: Icon(Icons.perm_identity),
        prefixText: "prefixText",
      ),
    );


在這里插入圖片描述

suffixIcon、suffixText

TextField(
      decoration: InputDecoration(
        //icon: Icon(Icons.person),
        hasFloatingPlaceholder: false,
        labelText: "labelText",
//        helperText: "helperText",
//        errorText: "errorText",
        // hintText: "hintText",
        prefixIcon: Icon(Icons.perm_identity),
        prefixText: "prefixText",
        suffixIcon: Icon(
          Icons.remove_red_eye,
        ),
        suffixText: "suffixText",
      ),
    );



在這里插入圖片描述

counterText

TextField(
      decoration: InputDecoration(
        //icon: Icon(Icons.person),
        hasFloatingPlaceholder: false,
        labelText: "labelText",
        // helperText: "helperText",
//        errorText: "errorText",
        // hintText: "hintText",
//        prefixIcon: Icon(Icons.perm_identity),
//        prefixText: "prefixText",
//        suffixIcon: Icon(
//          Icons.remove_red_eye,
//        ),
//        suffixText: "suffixText",

        counterText: "counterText",
      ),
    );



在這里插入圖片描述

filled,fillColor

顏色填充

TextField(
      decoration: InputDecoration(
        //icon: Icon(Icons.person),
        hasFloatingPlaceholder: false,
        labelText: "labelText",
        // helperText: "helperText",
//        errorText: "errorText",
         hintText: "hintText",
        prefixIcon: Icon(Icons.perm_identity),
//        prefixText: "prefixText",
//        suffixIcon: Icon(
//          Icons.remove_red_eye,
//        ),
//        suffixText: "suffixText",

       // counterText: "counterText",
        filled: true,
        fillColor: Colors.grey,
      ),
    );


在這里插入圖片描述

下面來看一下兩個輸入框的對比:

上面的輸入框代碼:

TextField(
      decoration: InputDecoration(
        icon: Icon(Icons.person),
       // hasFloatingPlaceholder: false,
        labelText: "labelText",
        helperText: "helperText",
        errorText: "errorText",
        hintText: "hintText",
        prefixIcon: Icon(Icons.perm_identity),
        prefixText: "prefixText",
        suffixIcon: Icon(
          Icons.remove_red_eye,
        ),
        suffixText: "suffixText",
        counterText: "counterText",
        filled: true,
       // fillColor: Colors.grey,
      ),
    );


下面的輸入框代碼:

TextField(
      decoration: InputDecoration(
        icon: Icon(Icons.person),
        prefixIcon: Icon(Icons.perm_identity),
        labelText: "手機號",
        helperText: "用戶名為手機號或者郵箱",
        errorText: "手機號碼不正確",
        hintText: "請輸入手機號碼",
        prefixText: "+86",
        suffixIcon: Icon(
          Icons.remove_red_eye,
        ),
        suffixText: "隱藏輸入文本",
        counterText: "0/10",
        filled: true,
      ),
    );


圖示:
在這里插入圖片描述

border、errorBorder、focusedBorder、focusedErrorBorder、disabledBorder、enabledBorder

不同狀態下的邊框樣式,他們接收值的類型都一樣,不過需要注意優先級。
大致分為一下幾種情況

1. 控件禁用時
當enabled為false時,如果指定了disabledBorder,優先使用disabledBorder,沒有的話設置disabledBorder則使用border的部分樣式(顏色默認是灰色)

2. 控件啟用(enable為true),但errorText有值
輸入框沒有焦點時,優先使用errorBorder的樣式,輸入框有焦點時,優先使用focusedErrorBorder,如果這兩個都沒有設置則使用border的部分樣式(顏色默認是紅色)

3. 控件啟用狀態,且errorText沒有值
輸入框沒有焦點時,優先使用enabledBorder ,有焦點時,優先使用focusedBorder,兩者均沒有指定時,使用默認的border

總體來說,默認的border優先級別較低。
建議:

  1. 在開發過程中我們如果需要errorText的話,我們只需要設置 errorBorder、focusedErrorBorder這三個即可。不需要errorText的話
  2. 不需要errorText的話,只需要設置enabledBorder 、focusedBorder

下面我們來看一下border的值

1. InputBorder.none 沒有任何邊框

代碼:

TextField(
      decoration: InputDecoration(
        border:InputBorder.none,
        labelText: "labelText",
        helperText: "helperText",
       // errorText: "errorText",
        hintText: "hintText",
        prefixIcon: Icon(Icons.perm_identity),
      ),
    );




在這里插入圖片描述

2. OutlineInputBorder(外邊線)
代碼:

TextField(
      decoration: InputDecoration(
        enabledBorder: OutlineInputBorder(
          /*邊角*/
          borderRadius: BorderRadius.all(
            Radius.circular(30), //邊角為30
          ),
          borderSide: BorderSide(
            color: Colors.amber, //邊線顏色為黃色
            width: 2, //邊線寬度為2
          ),
        ),
        focusedBorder: OutlineInputBorder(
            borderSide: BorderSide(
          color: Colors.green, //邊框顏色為綠色
          width: 5, //寬度為5
        )),
        labelText: "labelText",
        helperText: "helperText",
        // errorText: "errorText",
        hintText: "hintText",
        prefixIcon: Icon(Icons.perm_identity),
      ),
    );




在這里插入圖片描述

2. UnderlineInputBorder(底邊線,默認就是這個)

TextField(
      decoration: InputDecoration(
        errorBorder: UnderlineInputBorder(
          /*邊角*/
          borderRadius: BorderRadius.all(
            Radius.circular(30), //邊角為30
          ),
          borderSide: BorderSide(
            color: Colors.amber, //邊線顏色為黃色
            width: 2, //邊線寬度為2
          ),
        ),
        focusedErrorBorder: UnderlineInputBorder(
            borderSide: BorderSide(
          color: Colors.green, //邊框顏色為綠色
          width: 5, //寬度為5
        )),
        labelText: "labelText",
        helperText: "helperText",
         errorText: "errorText",
        hintText: "hintText",
        prefixIcon: Icon(Icons.perm_identity),
      ),
    );



在這里插入圖片描述

到這里基本上InputDecoration的屬性都介紹完畢了。


keyboardType

鍵盤的類型,常用值如下,比較簡單

在這里插入圖片描述

TextField(
      decoration: InputDecoration(
        labelText: "labelText",
        helperText: "helperText",
        errorText: "errorText",
        hintText: "hintText",
        prefixIcon: Icon(Icons.perm_identity),
      ),

      keyboardType: TextInputType.phone, //手機號
    );



可以看到 鍵盤變成了數字鍵盤,其他的值就不在演示了。
在這里插入圖片描述


TextField textInputAction

鍵盤操作按鈕的類型,接收一個TextInputAction 類型的值。

TextInputAction 是一個枚舉類型,值如下,其中有些值需要考慮Android和ios是否兼容的問題

enum TextInputAction {
//沒有任何動作
  none,
  
//讓操作系統決定哪個動作更合適
  unspecified,
  
//完成動作,一般會顯示“完成”二字
  done,
  
  /// 跳轉動作,一般用於輸入了一個超鏈接后執行該動作。鍵盤上會顯示“前往”二字
  go,
//搜索動作
  search,

//發送
  send,

  ///下個
  next,

  /// 返回前一個
  previous,

//繼續動作,在Android上好像沒反應,不顯示鍵盤
  continueAction,

//在Android上好像沒反應,不顯示鍵盤
  route,

//撥打緊急電話,在Android上好像沒反應,不顯示鍵盤
  emergencyCall,

//換行
  newline,
}



例如:

textInputAction: TextInputAction.search,

在這里插入圖片描述

textInputAction: TextInputAction.go,

在這里插入圖片描述


TextField onChanged

輸入文本發生變化時的回調,參數即為輸入框中的值

 onChanged: (val) {
        print(val);
      },



TextField onEditingComplete

點擊鍵盤的動作按鈕時的回調,沒有參數

  onEditingComplete: (){
        print("點擊了鍵盤上的動作按鈕");
      },



TextField onSubmitted

點擊鍵盤的動作按鈕時的回調,參數為當前輸入框中的值

  onSubmitted: (val){
        print("點擊了鍵盤上的動作按鈕,當前輸入框的值為:${val}");
      },


TextField inputFormatters

用於限制輸入的內容,接收一個TextInputFormatter 類型的集合。

TextInputFormatter是一個抽象類,
源碼如下:
在這里插入圖片描述

繼承關系如下
官方給我們提供了三種校驗方法,分別是

  1. WhitelistingTextInputFormatter 白名單校驗,也就是只允許輸入符合規則的字符
  2. BlacklistingTextInputFormatter 黑名單校驗,除了規定的字符其他的都可以輸入
  3. LengthLimitingTextInputFormatter 長度限制,跟maxLength作用類似

在這里插入圖片描述

WhitelistingTextInputFormatter

首先我們來看看白名單,
部分源碼如下:
在這里插入圖片描述
他接受一個Pattern類型的參數,Pattern是一個接口,而RegExp實現了Pattern接口,

在這里插入圖片描述

看到RegExp是不是很熟悉了,這不就是正則表達式么,那這樣就好辦了。

下面我們用一下白名單:

inputFormatters: [WhitelistingTextInputFormatter(RegExp("[a-z]"))],


例如,我們只允許輸入小寫的a到z。

在這里插入圖片描述

BlacklistingTextInputFormatter
黑名單跟白名單用法類似,這里我就直接用了

  inputFormatters: [BlacklistingTextInputFormatter(RegExp("[a-z]"))],


除了小寫的a到z都可以輸入

在這里插入圖片描述

LengthLimitingTextInputFormatter

限制輸入的長度
這里我們配合之前的黑名單一起使用

 inputFormatters: [
        BlacklistingTextInputFormatter(RegExp("[a-z]")),
        LengthLimitingTextInputFormatter(5)
      ],



在這里插入圖片描述


TextField controller

controller常用於賦值和取值操作

示例代碼:

import 'package:flutter/material.dart';

class TextFieldWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _TextFieldState();
  }
}

class _TextFieldState extends State<TextFieldWidget> {
  TextEditingController _userEtController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("TextField"),
      ),
      body: Container(
        padding: EdgeInsets.all(10),
        child: Column(
          children: <Widget>[
            TextField(
              controller: _userEtController,
            ),
            RaisedButton(
              child: Text("賦值"),
              onPressed: () {
                setState(() {
                  _userEtController.text = "15937600635";
                });
              },
            ),
            RaisedButton(
              child: Text("獲取值"),
              onPressed: () {
                setState(() {});
              },
            ),
            Text(_userEtController.text),
          ],
        ),
      ),
    );
  }
}




如下:
在這里插入圖片描述


如果你覺得本文對你有幫助,麻煩動動手指頂一下,算是對本文的一個認可。也可以關注我的  Flutter 博客專欄,我會不定期的更新,如果文中有什么錯誤的地方,還望指正,轉載請注明轉自喻志強的博客 ,謝謝!

 

 

 

Flutter TextField詳解

Realank
52018.10.23 11:48:50字數 497閱讀 62,299

實現TextField說簡單也簡單,說有坑,坑也不小,下面從易到難介紹一下使用

1.最簡單的就是無參數調用構造方法:

TextField() 
 

2.光有輸入框還不行,還得獲取其中的內容,所以需要傳遞controller:

import 'package:flutter/material.dart'; class TextFieldPage extends StatelessWidget { Widget buildTextField(TextEditingController controller) { return TextField( controller: controller, ); } 

我通過給controller添加通知來獲取TextField的值,這種使用場景不一定合適,更多的時候是在點擊按鈕的時候直接讀取controller.text的值

3.另外TextFiled還有一下小的屬性:

import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class TextFieldPage extends StatelessWidget { Widget buildTextField(TextEditingController controller) { return TextField( controller: controller, maxLength: 30,//最大長度,設置此項會讓TextField右下角有一個輸入數量的統計字符串 maxLines: 1,//最大行數 autocorrect: true,//是否自動更正 autofocus: true,//是否自動對焦 obscureText: true,//是否是密碼 textAlign: TextAlign.center,//文本對齊方式 style: TextStyle(fontSize: 30.0, color: Colors.blue),//輸入文本的樣式 inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],//允許的輸入格式 onChanged: (text) {//內容改變的回調 print('change $text'); }, onSubmitted: (text) {//內容提交(按回車)的回調 print('submit $text'); }, enabled: true,//是否禁用 ); } 
 

4.接着我還能顯示placeholder

decoration可以給TextField添加裝飾

TextField( decoration: InputDecoration(fillColor: Colors.blue.shade100, filled: true, labelText: 'Hello'), ); 

fillColor設置填充顏色,labelText設置標簽文字,這個標簽在沒有輸入的時候是占滿輸入框的,當輸入聚焦以后,就會縮小到輸入框左上角:

 

 

 
TextField( decoration: InputDecoration( fillColor: Colors.blue.shade100, filled: true, hintText: 'Hello', errorText: 'error'), ); 

hintText就是普通的placeholder,輸入后就不顯示了,errorText是錯誤提示

 

 

 

5.還能顯示一些別的裝飾

import 'package:flutter/material.dart'; class TextFieldPage extends StatelessWidget { Widget buildTextField() { return TextField( decoration: InputDecoration( fillColor: Colors.blue.shade100, filled: true, helperText: 'help', prefixIcon: Icon(Icons.local_airport), suffixText: 'airport'), ); } 
 

6.這些還不過癮,我不喜歡這個安卓風格的下面的裝飾線,我想變成圓角矩形的邊框

import 'package:flutter/material.dart'; class TextFieldPage extends StatelessWidget { Widget buildTextField() { return TextField( decoration: InputDecoration( contentPadding: EdgeInsets.all(10.0), border: OutlineInputBorder( borderRadius: BorderRadius.circular(15.0), // borderSide: BorderSide(color: Colors.red, width: 3.0, style: BorderStyle.solid)//沒什么卵效果 )), ); } 
 

7.改變裝飾線顏色

無論是下面的裝飾線,還是矩形邊框裝飾線,對焦后顯示的顏色,都是主題顏色的primaryColor,失去焦點以后就是黑色,這顯然不能滿足自定義的需求,但是通過各種努力發現,改變邊框顏色很困難,最后發現了這個答案:https://stackoverflow.com/questions/49600139/how-to-change-textfield-underline-color

所以正確的設置邊框顏色的方式是這樣的:

import 'package:flutter/material.dart'; class TextFieldPage extends StatelessWidget { Widget buildTextField() { return Theme( data: new ThemeData(primaryColor: Colors.red, hintColor: Colors.blue), child: TextField( decoration: InputDecoration( contentPadding: EdgeInsets.all(10.0), border: OutlineInputBorder( borderRadius: BorderRadius.circular(15.0), // borderSide: BorderSide(color: Colors.red, width: 3.0, style: BorderStyle.solid)//沒什么卵效果 )), ), ); } 
 

8.改變邊框的粗細

這些TextField的decoration徹底不能滿足要求了,需要重構成這種方式:


import 'package:flutter/material.dart'; class TextFieldPage extends StatelessWidget { Widget buildTextField() { return Container( padding: const EdgeInsets.all(8.0), alignment: Alignment.center, height: 60.0, decoration: new BoxDecoration( color: Colors.blueGrey, border: new Border.all(color: Colors.black54, width: 4.0), borderRadius: new BorderRadius.circular(12.0)), child: new TextFormField( decoration: InputDecoration.collapsed(hintText: 'hello'), ), ); } 
 

InputDecoration.collapsed可以禁用裝飾線,而是使用外面包圍的Container的裝飾線

致此,所有的輸入框的坑都趟完了,歡迎大家多多交流

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM