Flutter开发(十八)—— 表单

表单,页面中负责数据采集功能的控件。
在原生Android中EditText输入框,是重要的数据采集控件。而Flutter中TextField就是与EditText对应的重要的输入框控件,并且TextField属性和效果要比EditText强大不少。比如自带边框,输入动画等。

常用属性(具体的参考官方文档或查看源码):

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: 'helper required',//帮助提示信息
    hintText: '输入姓名',//提示语句
    prefixIcon: new Icon(Icons.games),//输入框最前面图标, prefix —— 前缀
    prefixText: 'Hello'),//输入框prefixIcon后面文字
),

以下为演示代码:
在main.dart中配置主题 和 根路由页面 FormPage.dart:

import 'package:flutter/material.dart';
import 'FormPage.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      initialRoute: '/', //使用带名称的路由,指定跟路由
      routes: {
        '/': (context) => FormPage(), // '/'路由  对应页面FormPage
      },

      theme: ThemeData(primaryColor: Colors.deepPurple),
    );
  }
}

根路由页面(FormPage.dart)中显示垂直布局Column,在其中放置两个TextField (在demo文件夹有 TextFieldDemo.dart 和 TextFieldDemo2.dart)。

import 'package:flutter/material.dart';
import 'demo/TextFieldDemo.dart';
import 'demo/TextFieldDemo2.dart';

class FormPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('FormPage'),
        centerTitle: true,  //title内容居中
      ),
      body: Theme(
        //重新定义主题
        data: ThemeData(
          primaryColor: Colors.white70,
        ),
        child: FromPageTest(),
      ),
    );
  }
}

class FromPageTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        color:Theme.of(context).primaryColor, //设置颜色跟随主题颜色(跟随最近设置的)
        padding: EdgeInsets.all(12.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            TextFieldDemo(),
            SizedBox(height: 10,),
            TextFieldDemo2(),
          ],
        ),
      );
  }
}

其中,TextFieldDemo.dart页面演示TextField的常用属性:

import 'package:flutter/material.dart';

class TextFieldDemo extends StatefulWidget {
  @override
  _TextFieldDemoState createState() => _TextFieldDemoState();
}

class _TextFieldDemoState extends State<TextFieldDemo> {
  @override
  Widget build(BuildContext context) {
    return TextField(
      //设置TextField 样式属性
      decoration: InputDecoration(
          icon: Icon(
            Icons.person,
            size: 28.0,
            color: Colors.deepPurple,
          ), //文本框左侧图标
          labelText: 'Name', //文本框标题
          hintText: '输入姓名', //提示语句

          // border: InputBorder.none,  //文本框没有边框
          //文本框有全边框,borderRadius设置边框倒角
          border: OutlineInputBorder(
            borderRadius: BorderRadius.all(Radius.circular(10)),
          ),

          // filled: true, //显示文本框背景颜色
          // fillColor: Colors.orange, //文本框背景颜色

          helperText: '以上需要您输入Name', //帮助提示信息
          helperStyle: TextStyle(fontSize: 12, color: Colors.red), //帮助提示信息Style

          suffixText: '@@' //后缀 邮箱 或者 金额需要这些
          ),
      // 监听每次输入字符
      onChanged: (value) {
        debugPrint('每次输入字符------:$value');
      },

      // 监听按下键盘确定按钮
      onSubmitted: (value) {
        debugPrint('按下确定按钮------:$value');
      },
      //
      onEditingComplete: () {
        debugPrint('--EditingComplete');
      },

      //修改键盘属性
      // keyboardType: TextInputType.number,
      // textInputAction: TextInputAction.continueAction,
      // textCapitalization: TextCapitalization.sentences,
    );
  }
}

在 TextFieldDemo2.dart 中使用另一种监听值输入的方式(TextEditingController),这个方式可以设定初始值:

import 'package:flutter/material.dart';

class TextFieldDemo2 extends StatefulWidget {
  @override
  _TextFieldDemo2State createState() => _TextFieldDemo2State();
}

class _TextFieldDemo2State extends State<TextFieldDemo2> {
  //TextEditingController步骤1
  final editingController = TextEditingController();

//TextEditingController步骤3  设置初始值,增加监听器
  @override
  void initState() {
    super.initState();
    editingController.text = '初始Name';
    editingController.addListener(() {
      debugPrint('Changed:${editingController.text}');
    });
  }

//TextEditingController步骤4 使用完 TextEditingController 需要注销 dispose
  @override
  void dispose() {
    editingController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      decoration: InputDecoration(
          icon: Icon(Icons.person_add), border: OutlineInputBorder()),

      //TextEditingController步骤2  监听输入 可设置初始值
      controller: editingController,
    );
  }
}

演示效果:
上边的是TextFieldDemo.dart,下边的是TextFieldDemo2.dart。
在这里插入图片描述

Flutter中的Form组件和html中的的作用类似,都是起到了一个容器的作用。里面可以包含多个TextFormField,便于多个输入框的统一管理和操作。
以下以用户注册为场景进行演示:
1、main.dart与前文中代码一样,只是作为根路由的引入;
2、FormPage.dart与前文基本一样,只是加入了RegisterForm.dart,而注释了其他展示控件;

import 'package:flutter/material.dart';
import 'demo/TextFieldDemo.dart';
import 'demo/TextFieldDemo2.dart';
import 'demo/RegisterForm.dart';

class FormPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('FormPage'),
        centerTitle: true,  //title内容居中
      ),
      body: Theme(
        //重新定义主题
        data: ThemeData(
          primaryColor: Colors.white70,
        ),
        child: FromPageTest(),
      ),
    );
  }
}

class FromPageTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        color:Theme.of(context).primaryColor, //设置颜色跟随主题颜色(跟随最近设置的)
        padding: EdgeInsets.all(12.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            // TextFieldDemo(),
            // SizedBox(height: 10,),
            // TextFieldDemo2(),
            // SizedBox(height: 20,),
            RegisterFrom(),//注册页面
          ],
        ),
      );
  }
}

3、RegisterFrom.dart注册页面代码逻辑。
其中展示了:
①、Form 与 TextFormField纵向布局的用法;
②、obscureText使输入内容变为小黑点展示;
③、validator 进行输入内容验证;
④、autovalidate 进行自动验证,并扩展为 初始默认不自动验证,当提交验证不通过时,才开启自动验证功能。

import 'package:flutter/material.dart';

class RegisterFrom extends StatefulWidget {
  @override
  _RegisterFromState createState() => _RegisterFromState();
}

class _RegisterFromState extends State<RegisterFrom> {
  //声明GlobalKey<FormState> 便于下面进行保存信息的操作
  final registerKey = GlobalKey<FormState>();
  String username, password; //定义需要保存的值的变量
  bool autovalidate = false; //默认不进行自动验证

  @override
  Widget build(BuildContext context) {
    return Form(
      key: registerKey,
      child: Column(
        children: <Widget>[
          TextFormField(
            decoration: InputDecoration(labelText: '用户:', helperText: ''),
            onSaved: (value) {
              username = value; //将输入的值,赋值给username
            },
            validator: validatorUsername, //添加验证
            autovalidate: autovalidate, //validator是否进行自动验证
          ),
          TextFormField(
            obscureText: true, //输入内容显示成小圆点
            decoration: InputDecoration(labelText: '密码:', helperText: ''),
            onSaved: (value) {
              password = value; //将输入的值,赋值给password
            },
            validator: validatorPassword, //添加验证
            autovalidate: autovalidate,
          ),
          //使注册按钮和 输入框直接有一定间距
          SizedBox(
            height: 20.0,
          ),
          Container(
            width: double.infinity,
            child: RaisedButton(
              color: Theme.of(context).accentColor, //以主题颜色
              child: Text(
                '注册',
                style: TextStyle(color: Colors.white),
              ),
              elevation: 0.0,
              onPressed: submitFrom, //不设置onPressed 按钮为灰色,不显示设定颜色
            ),
          ),
        ],
      ),
    );
  }

  //点击注册按钮,进行的逻辑动作
  //默认不进行自动验证,autovalidate = false,点击注册时,才会打开自动验证功能。
  void submitFrom() {
    // registerKey.currentState.validate(); 进行当前信息验证,这里会返回bool值
    if (registerKey.currentState.validate()) {
      registerKey.currentState.save(); //保存当前输入信息
      //底部弹出 SnackBar
      Scaffold.of(context).showSnackBar(SnackBar(
        content: Text('正在注册.... 用户:$username ,密码:$password'),
      ));
    } else {
      setState(() {
        autovalidate = true; //有空值,开启自动验证
      });
    }
  }

  //验证Password
  String validatorPassword(value) {
    if (value.isEmpty) {
      return '密码不为空!';
    }

    return null;
  }

  //验证Username
  String validatorUsername(value) {
    if (value.isEmpty) {
      return '用户名不为空!';
    }

    return null;
  }
}

效果展示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值