【Flutter學習】基本組件之基本表單組件


一,概述

    表單時一個包含表單元素的區域。 表單元素允許用戶輸入內容,比如文本域,下拉列表,單選框,復選框等。常見的應用場景有:登錄注冊輸入信息等。

表單里有兩個重要的組件:

  • Form:用來做整個表單提交使用  
  • TextFormField:用來做用戶輸入。  

    正式向服務器提交數據前,都會對各個輸入框數據進行合法性校驗。但對每個TextField都分別校驗很麻煩。

如果想清除一組TextfFiled的內容,一個個清除也很麻煩。所以,Flutter提供了一個Form widget,可以對輸入框進行分組,然后進行一些統一的操作。

二,構造函數

  • Form:
    • 介紹:Form繼承自StatefulWidget對象,它對應的狀態類為FormState
    • 構造函數:
      const Form({
          Key key,
          @required this.child,
          this.autovalidate = false,
          this.onWillPop,
          this.onChanged,
        }) : assert(child != null),
             super(key: key);
    • 參數含義

      autovalidate:是否自動校驗輸入內容;當為 true 時,每一個子FormField內容發生變化時都會自動校驗合法性,並直接顯示錯誤信息。否則,需要通過調用 FormState.validate() 來手動校驗.
      onWillPop:決定Form所在的路由是否可以直接返回(如點擊返回按鈕),該回調返回一個 Future 對象,如果Future的最終結果是false,則當前路由不會返回;如果為 true ,則會返回到上一個路由。此屬性通常用於攔截返回按鈕。
      onChanged:Form的任意一個子FormField內容發生變化時會觸發此回調。
  • FormField:
    • 介紹:Form的子孫元素必須是FormField類型,FormField是一個抽象類,定義幾個屬性,FormState內 部通過它們來完成操作
    • 構造函數:
      const FormField({
          Key key,
          @required this.builder,
          this.onSaved,
          this.validator,
          this.initialValue,
          this.autovalidate = false,
          this.enabled = true,
        }) : assert(builder != null),
             super(key: key);
    • 參數含義:
      FormFieldSetter<T> onSaved, //保存回調
      FormFieldValidator<T> validator, //驗證回調
      T initialValue, //初始值
      bool autovalidate = false, //是否自動校驗。
    • 補充:Flutter提供了一個TextFormField widget,它繼承自FormField類,也是 TextField的一個包裝類,所以除了FormField定義的屬性之外,它還包括TextField的屬性。
  • FormState:
    • 介紹:FormState為Form的State類,可以通過 Form.of() 或GlobalKey獲得。可以通過它來對 Form的子孫FormField進行統一操作。
    • 構造函數:無自定義構造函數
    • 常用的三個方法:
      FormState.validate() :調用此方法后,會調用Form子孫FormField的validate回調,如 果有一個校驗失敗,則返回false,所有校驗失敗項都會返回用戶返回的錯誤提示。
      FormState.save() :調用此方法后,會調用Form子孫FormField的save回調,用於保存表單 內容.
      FormState.reset() :調用此方法后,會將子孫FormField的內容清空。

三,TextField, FormField

  • 從最基礎的講起,對於TextField就是android中的edittext,就是一個輸入框( TextField class),這個輸入框常用的屬性如下:
    child: new TextField(
    autocorrect: false, // 是否自動校正
    autofocus: false, //自動獲取焦點
    enabled: true, // 是否啟用
    inputFormatters: [], //對輸入的文字進行限制和校驗
    keyboardType: TextInputType.text, //獲取焦點時,啟用的鍵盤類型
    maxLines: 2, // 輸入框最大的顯示行數
    maxLength: 3, //允許輸入的字符長度/
    maxLengthEnforced: false, //是否允許輸入的字符長度超過限定的字符長度
    obscureText: true, // 是否隱藏輸入的內容
    onChanged: (newValue) {
    // print(newValue); // 當輸入內容變更時,如何處理
    },
    onSubmitted: (value) {
    // print("whar"); // 當用戶確定已經完成編輯時觸發
    },
    style: new TextStyle(
    color: new Color(Colors.amberAccent.green)), // 設置字體樣式
    textAlign: TextAlign.center, //輸入的內容在水平方向如何顯示
    decoration: new InputDecoration(
    labelText: "城市",
    icon: new Icon(Icons.location_city),
    border: new OutlineInputBorder(), // 邊框樣式
    helperText: 'required',
    hintText: '請選擇你要投保的城市',
    prefixIcon: new Icon(Icons.android),
    prefixText: 'Hello'),
    ),
  • 輸入處理

    其實對於一個輸入框,我們最關心的無非就是監聽輸入的內容,然后輸入完成后,輸入框中的內容是什么,文檔中寫的很清楚,textfiled控件有三個回調函數

    在這里我們只需要關注onChanged和onSubmitted即可。

    child: new TextField(
     controller: _controller,
     decoration: new InputDecoration(labelText: 'Your Name'),
     onChanged: (val) {
      print(val);
     },
     onSubmitted: (String v) {
      print(v);
     },
    ),
  • 顧名思義:
      onChanged事件,在輸入內容發生變化的時候觸發,onSubmitted事件,則是在輸入結束,點擊完成的時候觸發。 然而在TextFormField中沒有這兩個事件,取而代之的是validator,onSaved,onFieldSubmitted 他們都接受三個函數,並且將其值作為參數傳遞到函數里面validator,如果開啟autovalidate: true,那么將會自動檢驗輸入的值,如果沒有則會在表單提交的時候檢驗 該函數只允許返回驗證失敗的錯誤信息以及驗證通過時返回null。onSaved, 當調用FormState.save方法的時候調用。onFieldSubmitted, 與onSubmitted一樣,則是在輸入結束,點擊完成的時候觸發。
  • 編輯控制

      無論是在TextField還是TextFormField中,都有一個重要的屬性controller,該屬性可用來對輸入框內容進行控制。 先創建一個控制對象:

    TextEditingController _controller = new TextEditingController();
    TextEditingController _formFieldController = new TextEditingController();

    為輸入框初始化值以及注冊一個監聽事件:

    @override
    void initState() {
    // TODO: implement initState
    super.initState();
      _controller.value = new TextEditingValue(text: 'Hello');
      _formFieldController.addListener(() {
      print('listener');
      });
    }

    觸發一個監聽事件:

    void _textFieldAction() {
      // print(_formFieldController.selection);
      // print(_formFieldController.text); //獲取輸入內容
      print(_formFieldController.hasListeners); //判斷是否注冊監聽事件
      _formFieldController.notifyListeners(); //觸發監聽事件
    }

四,示例代碼  

import 'package:flutter/material.dart';
 
void main() => runApp(new HomePage());
 
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => new _HomePageState();
}
 
class _HomePageState extends State<HomePage> {
  GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
  String _name;
  String _password;
 
  void _forSubmitted() {
    var _form = _formKey.currentState;
    if (_form.validate()) {
      _form.save();
      print(_name);
      print(_password);
    }
  }
 
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new MaterialApp(
      title: 'Flutter data',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Flutter Form'),
        ),
        floatingActionButton: new FloatingActionButton(
          onPressed: _forSubmitted,
          child: new Text('提交'),
        ),
        body: new Container(
          padding: const EdgeInsets.all(16.0),
          child: new Form(
            key: _formKey,
            child: new Column(
              children: <Widget>[
                new TextFormField(
                  decoration: new InputDecoration(
                    labelText: 'Your Name',
                  ),
                  onSaved: (val) {
                    _name = val;
                  },
                ),
                new TextFormField(
                  decoration: new InputDecoration(
                    labelText: 'Password',
                  ),
                  obscureText: true,
                  validator: (val) {
                    return val.length < 4 ? "密碼長度錯誤" : null;
                  },
                  onSaved: (val) {
                    _password = val;
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

五,官方文檔
表單 Widgets

 


免責聲明!

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



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