flutter TextField 輸入框元件

__white發表於2021-08-07

這是我參與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獲得焦點時,圖示會自動變色,提示文字會自動上移。

這裡寫圖片描述

還可以看到 我加了一個onChangedonChanged是每次輸入框內每次文字變更觸發的回撥,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。

github原始碼

相關文章