3.7 输入框和表单

输入框有TextField、带有iOS风格的CupertinoTextField,还有表单form.

3.7.1 TextField

TextField默认带有下划线,无边框的,属性InputDecoration可以设置默认文字,当编辑状态,文字已动画形式上浮至左上角,这是其他输入框所没有的。其他的看下属性:

const TextField({
    ...
    this.controller,
    this.focusNode,
    this.decoration = const InputDecoration(),
    TextInputType keyboardType,
    this.textInputAction,
    this.style,
    this.textAlign = TextAlign.start,
    this.textAlignVertical,
    this.textDirection,
    this.showCursor,
    this.autofocus = false,
    this.obscureText = false,
    this.enableSuggestions = true,
    this.maxLines = 1,
    this.minLines,
    this.expands = false,
    this.maxLength,
    this.onChanged,
    this.onEditingComplete,
    this.onSubmitted,
    this.inputFormatters,
    this.enabled,
    this.cursorWidth = 2.0,
    this.cursorRadius,
    this.cursorColor,
    ...
  })
  • controller可以获取文字和设置文字,
  • focusNode 获取焦点
  • keyboardType键盘类型
  • textInputAction输入键盘右下角的键
  • onChangedtextFieldvalue变化回调函数
  • onSubmitted提交按键
  • obscureText true则显示原点,否则显示原文字
  • cursorWidth光标宽度
  • cursorRadius 光标圆圈半径
  • cursorColor光标颜色

textInputAction有多个值,具体见下表格:

textInputAction 备注
none AndroidIME_ACTION_NONE,iOS没有
unspecified Android's IME_ACTION_UNSPECIFIED,iOSreturn
done Android's IME_ACTION_DONE iOSdone
go android and iOS 都是go
search android and ios is Search
send android and ios is send
next android and ios is next
previous iOS没有,Android's IME_ACTION_PREVIOUS
continueAction Android没有,iOS上是contion
join android and ios is join
route android没有,ios is route
emergencyCall android没有,ios is Emergency Call
newline android and ios都没有,只是方便开发人员调试

例子:

_focusNode = new FocusNode();
_editingController = new TextEditingController();
_field = TextField(
  focusNode: _focusNode,
  onChanged: (v) {
    setState(() {});
  },
  onSubmitted: (v) {
    _focusNode.unfocus();
  },
  controller: _editingController,
  obscureText: false, //是否是密码
  decoration: InputDecoration(hintText: '手机号', labelText: '手机号'),
  keyboardType: TextInputType.number,
);

Column(
      children: <Widget>[
        Text('TextField'),
        _field,
        Text(_editingController.value.text),

      ],
    )

效果如下:

iOS-style的组件CupertinoTextField,属性和TextField基本一致;

例子:

_editingController2 = new TextEditingController();
_focusNode2 = new FocusNode();
_cupertinoTextField = CupertinoTextField(
  focusNode: _focusNode2,
  controller: _editingController2,
  placeholder: '密码',
  prefix: Icon(Icons.lock),
  textInputAction: TextInputAction.go,
  obscureText: true,
);



Column(
      children: <Widget>[
        SizedBox(
          height: 30,
        ),
        Text('CupertinoTextField'),
        _cupertinoTextField,
      ],
    )

效果:

监听文本变化

 _editingController = new TextEditingController()
      ..addListener(() {
        print("${_editingController.value.text}");
      });

或者

TextField(
      focusNode: _focusNode,
      onChanged: (v) {
        print('onChange$v');
      },
      controller: _editingController,
...
    );

收键盘


TextField(
      focusNode: _focusNode,
    );
/// 收键盘
_focusNode.unfocus();

收键盘之前必须在初始化的时候赋值给TextField,另外官方还提供了编辑下一个textField,当下边没有可以提供编辑的textField则进行书键盘操作,有的话则跳至下一个textField.

_focusNode.focusInDirection(TraversalDirection.down);

3.7.2 Form

Form更新数据和获取数据需要使用_globalKey获取当前的State

例子:

Form(
  key: _globalKey,
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      TextFormField(
        decoration: const InputDecoration(
          hintText: 'Enter your email',
        ),
        validator: (value) {
          if (value.isEmpty) {
            return 'Please enter some text';
          }
          return null;
        },
      ),
      Padding(
        padding: const EdgeInsets.symmetric(vertical: 16.0),
        child: RaisedButton(
          onPressed: () {
            // Validate will return true if the form is valid, or false if
            // the form is invalid.
            if (_globalKey.currentState.validate()) {
              // Process data.
            }
          },
          child: Text('Submit'),
        ),
      ),
    ],
  ),
)

Form子树中可以是多个TextFormField,每个可以单个校验,所有的都校验过了,FormState才是校验通过的,多用于多输入校验。那么我们写一个登陆的简单校验。

例子:

_form = Form(
  key: _globalKey,
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      TextFormField(
        decoration: const InputDecoration(
            hintText: 'Enter your email', icon: Icon(Icons.mail)),
        validator: (value) {
          if (value.isEmpty) {
            return 'Please enter some text';
          }
          return null;
        },
      ),
      TextFormField(
          controller: _editingController3,
          decoration: InputDecoration(
              labelText: "密码", hintText: "您的登录密码", icon: Icon(Icons.lock)),
          obscureText: true,
          //校验密码
          validator: (v) {
            return v.trim().length > 5 ? null : "密码不能少于6位";
          }),
      Padding(
        padding: const EdgeInsets.symmetric(vertical: 16.0),
        child: RaisedButton(
          onPressed: () {
            // Validate will return true if the form is valid, or false if
            // the form is invalid.
            if (_globalKey.currentState.validate()) {
              // Process data.
              print('校验通过');
            }
            setState(() {
              _done = _globalKey.currentState.validate();
            });
          },
          child: Text('Submit'),
        ),
      ),
    ],
  ),
);

results matching ""

    No results matching ""