Flutter輸入框及表單

Material組件庫中提供了輸入框組件TextField和表單組件Form各谚。下面我們分別介紹一下迄薄。

  • 組件 - TextField
  • 表單Form

1. 組件 - TextField

TextField用于文本輸入

屬性包括:

  • controller:編輯框的控制器凝颇,通過它可以設(shè)置/獲取編輯框的內(nèi)容、選擇編輯內(nèi)容叽讳、監(jiān)聽編輯文本改變事件拟蜻。大多數(shù)情況下我們都需要顯式提供一個controller來與文本框交互。如果沒有提供controller震捣,則TextField內(nèi)部會自動創(chuàng)建一個荔棉。

  • focusNode:用于控制TextField是否占有當前鍵盤的輸入焦點闹炉。它是我們和鍵盤交互的一個句柄 (handle)。

  • InputDecoration:用于控制TextField的外觀顯示润樱,如提示文本渣触、背景顏色、邊框等壹若。

  - labelText:  "用戶名",
  - hintText: "用戶名或郵箱",
  - prefixIcon: Icon(Icons.person)
  - // 未獲得焦點下劃線設(shè)為灰色
    enabledBorder: UnderlineInputBorder(
      borderSide: BorderSide(color: Colors.grey),
    ),
  -  //獲得焦點下劃線設(shè)為藍色
    focusedBorder: UnderlineInputBorder(
      borderSide: BorderSide(color: Colors.blue),
    ),
  • keyboardType:用于設(shè)置該輸入框默認的鍵盤輸入類型嗅钻,取值如下:
  - text    文本輸入鍵盤
  - multiline   多行文本,需和maxLines配合使用(設(shè)為null或大于1)
  - number  數(shù)字店展;會彈出數(shù)字鍵盤
  - phone   優(yōu)化后的電話號碼輸入鍵盤养篓;會彈出數(shù)字鍵盤并顯示“* #”
  - datetime    優(yōu)化后的日期輸入鍵盤;Android上會顯示“: -”
  - emailAddress    優(yōu)化后的電子郵件地址赂蕴;會顯示“@ .”
  - url 優(yōu)化后的url輸入鍵盤柳弄; 會顯示“/ .”
  • textInputAction:鍵盤動作按鈕圖標(即回車鍵位圖標)

  • style:正在編輯的文本樣式。

  • textAlign: 輸入框內(nèi)編輯文本在水平方向的對齊方式概说。

  • autofocus: 是否自動獲取焦點碧注。

  • obscureText:是否隱藏正在編輯的文本,如用于輸入密碼的場景等糖赔,文本內(nèi)容會用“?”替換萍丐。

  • maxLines:輸入框的最大行數(shù),默認為1放典;如果為null逝变,則無行數(shù)限制。

  • maxLength和maxLengthEnforced :maxLength代表輸入框文本的最大長度奋构,設(shè)置后輸入框右下角會顯示輸入的文本計數(shù)骨田。
    maxLengthEnforced決定當輸入文本長度超過maxLength時是否阻止輸入,為true時會阻止輸入声怔,為false時不會阻止輸入但輸入框會變紅态贤。

  • onChange:輸入框內(nèi)容改變時的回調(diào)函數(shù);注:內(nèi)容改變事件也可以通過controller來監(jiān)聽醋火。

  • onEditingComplete和onSubmitted:這兩個回調(diào)都是在輸入框輸入完成時觸發(fā)悠汽,比如按了鍵盤的完成鍵(對號圖標)或搜索鍵(??圖標)。不同的是兩個回調(diào)簽名不同芥驳,onSubmitted回調(diào)是ValueChanged<String>類型柿冲,它接收當前輸入內(nèi)容做為參數(shù),而onEditingComplete不接收參數(shù)兆旬。

  • inputFormatters:用于指定輸入格式假抄;當用戶輸入內(nèi)容改變時,會根據(jù)指定的格式來校驗。

  • enable:如果為false宿饱,則輸入框會被禁用熏瞄,禁用狀態(tài)不接收輸入和事件,同時顯示禁用態(tài)樣式(在其- decoration中定義)谬以。

  • cursorWidth强饮、cursorRadius和cursorColor:這三個屬性是用于自定義輸入框光標寬度、圓角和顏色的为黎。


當獲取一個文本框輸入的值時邮丰,代碼示例

// 定一個controller
TextEditingController _textController= TextEditingController();

TextField(
    autofocus: true,
    controller: _textController, //設(shè)置controller
    ...
)

// 獲取輸入框內(nèi)容
_textController.text

2. 表單Form

Flutter提供了一個Form 組件,它可以對輸入框進行分組铭乾,然后進行一些統(tǒng)一操作剪廉,如輸入內(nèi)容校驗、輸入框重置以及輸入內(nèi)容保存炕檩。

Form繼承自StatefulWidget對象妈经,它對應(yīng)的狀態(tài)類為FormState。我們先看看Form類的定義:

Form({
    Key key,
    @required this.child,
    this.autovalidate = false,
    this.onWillPop,
    this.onChanged,
  })
  • key: 通過key屬性捧书,來獲取表單對象。

  • child: 是表單里的一些布局骤星,結(jié)合TextFormField組件來實現(xiàn)表單的驗證经瓷。

  • autovalidate:是否自動校驗輸入內(nèi)容;當為true時洞难,每一個子FormField內(nèi)容發(fā)生變化時都會自動校驗合法性舆吮,并直接顯示錯誤信息。否則队贱,需要通過調(diào)用FormState.validate()來手動校驗色冀。

  • onWillPop:決定Form所在的路由是否可以直接返回(如點擊返回按鈕),該回調(diào)返回一個Future對象柱嫌,如果Future的最終結(jié)果是false锋恬,則當前路由不會返回;如果為true编丘,則會返回到上一個路由与学。此屬性通常用于攔截返回按鈕。

  • onChanged:Form的任意一個子FormField內(nèi)容發(fā)生變化時會觸發(fā)此回調(diào)嘉抓。

示例代碼如下:

class FormTest extends StatefulWidget {
  @override
  _FormTestState createState() => new _FormTestState();
}

class _FormTestState extends State<FormTest> {
  TextEditingController _unameController = new TextEditingController();
  TextEditingController _pwdController = new TextEditingController();
  GlobalKey _formKey= new GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title:Text("Form Test"),
      ),
      body: Padding(
        padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
        child: Form(
          key: _formKey, //設(shè)置globalKey索守,用于后面獲取FormState
          autovalidate: true, //開啟自動校驗
          child: Column(
            children: <Widget>[
              TextFormField(
                  autofocus: true,
                  controller: _unameController,
                  decoration: InputDecoration(
                      labelText: "用戶名",
                      hintText: "用戶名或郵箱",
                      icon: Icon(Icons.person)
                  ),
                  // 校驗用戶名
                  validator: (v) {
                    return v.trim().length > 0 ? null : "用戶名不能為空";
                  }

              ),
              TextFormField(
                  controller: _pwdController,
                  decoration: InputDecoration(
                      labelText: "密碼",
                      hintText: "您的登錄密碼",
                      icon: Icon(Icons.lock)
                  ),
                  obscureText: true,
                  //校驗密碼
                  validator: (v) {
                    return v.trim().length > 5 ? null : "密碼不能少于6位";
                  }
              ),
              // 登錄按鈕
              Padding(
                padding: const EdgeInsets.only(top: 28.0),
                child: Row(
                  children: <Widget>[
                    Expanded(
                      child: RaisedButton(
                        padding: EdgeInsets.all(15.0),
                        child: Text("登錄"),
                        color: Theme.of(context).primaryColor,
                        textColor: Colors.white,
                        onPressed: () {
                          // 通過_formKey.currentState 獲取FormState后,
                          // 調(diào)用validate()方法校驗用戶名密碼是否合法抑片,校驗
                          // 通過后再提交數(shù)據(jù)卵佛。 
                          if((_formKey.currentState as FormState).validate()){
                            //驗證通過提交數(shù)據(jù)
                          }
                        },
                      ),
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}


還可以通過Form.of(context)來驗證表單提交,如果直接在 onPressed 方法中獲取,是不可行的截汪,因為獲取到的上下文context為 FormTest的context疾牲,而FormState是在FormTest的子樹中, 所以需要通過Builder來構(gòu)建按鈕挫鸽,Builder會將widget節(jié)點的context作為回調(diào)參數(shù)说敏,代碼示例如下:

Expanded(
  child:Builder(builder: (context){
    return RaisedButton(
      onPressed: () {
        if(Form.of(context).validate()){
          //驗證通過提交數(shù)據(jù)
        }
      },
    );
  })
)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市丢郊,隨后出現(xiàn)的幾起案子盔沫,更是在濱河造成了極大的恐慌,老刑警劉巖枫匾,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件架诞,死亡現(xiàn)場離奇詭異,居然都是意外死亡干茉,警方通過查閱死者的電腦和手機谴忧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來角虫,“玉大人沾谓,你說我怎么就攤上這事〈炼欤” “怎么了均驶?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長枫虏。 經(jīng)常有香客問我妇穴,道長,這世上最難降的妖魔是什么隶债? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任腾它,我火速辦了婚禮,結(jié)果婚禮上死讹,老公的妹妹穿的比我還像新娘瞒滴。我一直安慰自己,他們只是感情好赞警,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布逛腿。 她就那樣靜靜地躺著,像睡著了一般仅颇。 火紅的嫁衣襯著肌膚如雪单默。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天忘瓦,我揣著相機與錄音搁廓,去河邊找鬼引颈。 笑死,一個胖子當著我的面吹牛境蜕,可吹牛的內(nèi)容都是我干的蝙场。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼粱年,長吁一口氣:“原來是場噩夢啊……” “哼售滤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起台诗,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤完箩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拉队,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弊知,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年粱快,在試婚紗的時候發(fā)現(xiàn)自己被綠了秩彤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡事哭,死狀恐怖漫雷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鳍咱,我是刑警寧澤降盹,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站流炕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仅胞。R本人自食惡果不足惜每辟,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望干旧。 院中可真熱鬧渠欺,春花似錦、人聲如沸椎眯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽编整。三九已至舔稀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掌测,已是汗流浹背内贮。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人夜郁。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓什燕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親竞端。 傳聞我的和親對象是個殘疾皇子屎即,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容