前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter中的常见表单组件

Flutter中的常见表单组件

作者头像
拉维
发布2019-08-29 17:28:01
4.8K0
发布2019-08-29 17:28:01
举报
文章被收录于专栏:iOS小生活iOS小生活

在Flutter中,常见的表单组件有TextField单行文本框、TextField多行文本框、CheckBox、Radio、Switch、CheckBoxListTile、RadioListTile、SwitchListTile、Slide等。

下面我将一一为大家做介绍。

TextField

TextField有如下常见属性:

  • maxLines,设置此参数可以将文本框改为多行文本框
  • onChanged,文本框改变的时候触发的事件
  • decoration——hintText,占位文字;border,配置文本框边框,一般设置为 OutlineInputBorder 类型;labelText,label的名称;labelStyle,配置label的样式。
  • obscureText,把文本框框改为密码框
  • controller,

首先我们来看一下TextField的基本用法:

代码语言:javascript
复制
Column(
        children: <Widget>[
          SizedBox(height: 10),
          TextField(
            decoration: InputDecoration(
              hintText: "请输入搜索内容(这是占位文字)", //占位文字
              border: OutlineInputBorder(), //输入框的边框
            ),
          ),
          SizedBox(height: 10),
          TextField(
            maxLines: 3, //设置此参数可以将文本框改为多行文本框
            decoration: InputDecoration(
              labelText: "多行文本框",
              border: OutlineInputBorder(),
            ),
          ),
          SizedBox(height: 10),
          TextField(
            obscureText: true, //把文本框框改为密码框
            decoration: InputDecoration(
              border: OutlineInputBorder(),
              labelText: "密码框labeltext",//配置了该属性,就会呈现一个特殊的效果,可以见示意图
              icon: Icon(Icons.people),//在文本框前面配置图标
              ),
          ),
        ],
      )

效果如下:

然后我们考虑,如何给输入框中的文字赋初始值呢?这时就要用到controller了。代码如下:

代码语言:javascript
复制
import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  
  //第1步,声明TextField的控制器
  var _usernameController = TextEditingController();

  @override
  void initState() {
    super.initState();
    //第2步,在这里给输入框赋初始值
    _usernameController.text = "这是输入框中的初始值";
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(10),
      child: Column(
        children: <Widget>[
          TextField(
            decoration: InputDecoration(
              border: OutlineInputBorder(),
              labelText: "用户名"
            ),
            //第3步,给TextField绑定controller
            controller: _usernameController,
          )
        ],
      ),
    );
  }
}

效果如下:

那么如何获取TextField中输入的内容呢?

其实很简单,我们接着上面的代码,只需要通过 _usernameController.text 就可以获取到对应的输入框中的文字了。下面是点击按钮获取输入框中文字的代码:

代码语言:javascript
复制
RaisedButton(
            onPressed: (){
              print(_usernameController.text);
            },
            child: Text("获取输入框中的文字"),
          )

我们再想一下,如何通过不使用配置controller来获取到输入框中的文字呢?我们可以通过配置 TextField 的 onChanged 回调来监听输入框中文字的实时变化

代码语言:javascript
复制
import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  //第1步,声明一个属性,记录输入框中文字
  String _usernameStr = "";

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(10),
      child: Column(
        children: <Widget>[
          TextField(
            //第2步,实时监听输入框中文字的改变
            onChanged: (textValue) {
              _usernameStr = textValue;
            },
            decoration:
                InputDecoration(border: OutlineInputBorder(), labelText: "用户名"),
          ),
          SizedBox(height: 20),
          Container(
            width: double.infinity, //宽度自适应
            child: RaisedButton(
              onPressed: () {
                //第3步,获取输入框中文字
                print(_usernameStr);
              },
              child: Text("获取输入框中的文字"),
            ),
          )
        ],
      ),
    );
  }
}

实际上,上面提到的配置TextField的controller,主要是为了给输入框中的文字赋初始值。如果是单纯地只想获取输入框中文字的话,我们可以另外定义一个变量,然后通过配置TextField的onChanged回调来监听文字的变化。

Checkbox、CheckboxListTile

Checkbox的常用属性如下:

  • value,true或者false,配置是否选中
  • onChanged,选中状态改变的时候的回调
  • activeColor,选中时的背景颜色
  • checkColor,选中时Checkbox里面对号的颜色

使用代码如下:

代码语言:javascript
复制
class _HomePageState extends State<HomePage> {
  
  bool _flag = true;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(10),
      child: Column(
        children: <Widget>[
          Checkbox(
            value: this._flag,//配置选中与否的值
            //监听选中状态的改变
            onChanged: (value){
              setState(() {
                this._flag = value;
              });
            },
            //选中时的背景颜色
            activeColor: Colors.pink,
            //选中时Checkbox里面对号的颜色
            checkColor: Colors.yellow,
          ),
          Text(this._flag?"选中":"未选中"),
        ],
      ),
    );
  }
}

效果如下:

Checkbox作为一个选中组件,仅仅提供了选中与否的最基本的视觉展示,如果想要扩展其他的内容,则需要自己去组装。Flutter为我们考虑到了这一点,所以给我们提供了CheckboxListTile组件

CheckboxListTile组件的属性如下:

  • value,true或者false,配置是否选中
  • onChanged,选中状态改变的时候的回调
  • activeColor,选中时的背景颜色
  • title,标题
  • subtitle,二级标题
  • secondary,配置图标或者图片
  • selected,选中的时候文字的颜色是否跟着改变为activeColor

代码如下:

代码语言:javascript
复制
Column(
        children: <Widget>[
          CheckboxListTile(
            value: this._flag,//配置选中与否的值
            //监听选中状态的改变
            onChanged: (value){
              setState(() {
                this._flag = value;
              });
            },
            //选中时的背景颜色
            activeColor: Colors.pink,
            //一级标题
            title: Text("一级标题"),
            //二级标题
            subtitle: Text("二级标题"),
            //配置图标或者图片
            secondary: Icon(Icons.home),
            //选中的时候,文字图标等的颜色是否都跟着改变
            selected: this._flag,
          ),
        ],
      )

效果如下:

Radio、RadioListTile

我们可以使用Checkbox来实现多选按钮组的视觉效果,如果想要实现单选按钮组的效果,可以使用Radio。

Radio的常见属性如下:

  • value,单选的值
  • onChanged,选中该条目的时候触发的函数
  • activeColor,选中时的背景颜色
  • groupValue,所在单选按钮组的选中值,要想配置几个Radio为一个单选按钮组,那么配置该属性值相同即可

使用代码如下:

代码语言:javascript
复制
class _HomePageState extends State<HomePage> {
  int _sex = 1;//默认选中男

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(10),
      child: Column(
        children: <Widget>[
          Row(
            children: <Widget>[
              Text("男"),
              Radio(
                //单选的值
                value: 1,
                //选中的时候回调
                onChanged: (value) {
                  setState(() {
                    this._sex = value;
                  });
                },
                //配置单选按钮组的选中值,所有该属性值相等的Radio都处于同一个按钮组下
                groupValue: this._sex,
              ),
              SizedBox(width: 20),
              Text("女"),
              Radio(
                value: 2,
                onChanged: (value) {
                  setState(() {
                    this._sex = value;
                  });
                },
                groupValue: this._sex,
              )
            ],
          ),
          Row(
            children: <Widget>[
              Text(this._sex==1?"男":"女"),
            ],
          )
        ],
      ),
    );
  }
}

运行效果如下:

关于上面的代码,这里再啰嗦几句。Radio可以用于实现单选按钮组,有三个属性是必须要配置的:value、onChanged、groupValue。如果某几个 Radio 的 groupValue 属性值配置相同,那么说明这几个Radio处于同一个单选按钮组

与Checkbox一样,Radio也是仅仅提供了最基本的选中视觉效果,如果想要丰富其他视觉内容的展现,我们需要自己去组装组件。Flutter考虑到这一点,所以为我们提供了一个RadioListTile组件

RadioListTile组件的属性如下:

  • value,单选的值
  • onChanged,选中时候的回调
  • activeColor,选中时的背景颜色
  • groupValue,单选组的值
  • title,标题
  • subtitle,次级标题
  • secondary,配置图标或者图片
  • selected,选中的时候文字的颜色是否跟着改变为activeColor

使用代码如下:

代码语言:javascript
复制
class _HomePageState extends State<HomePage> {
  int _sex = 1; //默认选中男

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(10),
      child: Column(
        children: <Widget>[
          RadioListTile(
            value: 1,//配置单选值
            groupValue: this._sex,//按钮组的值,该值相同说明在同一个按钮组下
            onChanged: (value) {//选中时候的回调
              setState(() {
                this._sex = value;
              });
            },
            title: Text("男"),//标题
            subtitle: Text("男的,雄性的"),//二级标题
            secondary: Icon(Icons.headset),//图标或者图片
            activeColor: Colors.red,//选中时的背景颜色
            selected: this._sex == 1,//选中的时候文字的颜色是否跟着改变为activeColor
          ),
          RadioListTile(
            value: 2,
            groupValue: this._sex,
            onChanged: (value) {
              setState(() {
                this._sex = value;
              });
            },
            title: Text("女"),
            subtitle: Text("女的,雌性的"),
            secondary: Icon(Icons.pregnant_woman),
            activeColor: Colors.red,
            selected: this._sex == 2,
          ),
          RadioListTile(
            value: 3,
            groupValue: this._sex,
            onChanged: (value) {
              setState(() {
                this._sex = value;
              });
            },
            title: Text("第三性别"),
            subtitle: Text("既不是男性,也不是女性"),
            secondary: Icon(Icons.tap_and_play),
            activeColor: Colors.red,
            selected: this._sex == 3,
          )
        ],
      ),
    );
  }
}

效果如下:

关于RadioListTile,有一点需要注意:

所有的ListTile(ListTile、CheckboxListTile、RadioListTile)都是竖直排列的,所以要放在竖直排列的组件(比如ListView、Column等)中,不能放在Row这样的水平排列的组件中

Switch开关

Switch是一个开关组件,常见属性如下:

  • value,bool类型,是否选中
  • onChanged,状态改变时触发回调
  • activeColor,选中的颜色、背景颜色

使用代码如下:

代码语言:javascript
复制
          Switch(
            value: this._flag,
            onChanged: (value){
              setState(() {
                this._flag = value;
              });
            },
          )

效果图如下:

实例

上面,我依次为大家讲述了TextField、Checkbox、CheckboxListTile、Radio、RadioListTile、Switch等表单组件。接下来,我将把这些表单组件组合起来,通过一个实例给大家更直观地展示一下这些组件的使用场景。

代码如下:

代码语言:javascript
复制
import 'package:flutter/material.dart';

class InfomationNewPage extends StatefulWidget {
  InfomationNewPage({Key key}) : super(key: key);

  _InfomationNewPageState createState() => _InfomationNewPageState();
}

class _InfomationNewPageState extends State<InfomationNewPage> {
  //用户姓名
  String _userName;
  //性别
  int _sex;
  //备注信息
  String _noteInfo;
  //兴趣爱好
  List _hobbies = [
    {"hobby": "吃饭", "selected": false},
    {"hobby": "睡觉", "selected": false},
    {"hobby": "喝水", "selected": false},
    {"hobby": "爬山", "selected": false},
    {"hobby": "攀岩", "selected": false},
    {"hobby": "潜水", "selected": false}
  ];

  //获取兴趣爱好组件组(多选组)
  List<Widget> _getHobbyWidgets() {
    List<Widget> hobbyWidgets = List();
    for (var i = 0; i < this._hobbies.length; i++) {
      Map map = this._hobbies[i];
      hobbyWidgets.add(CheckboxListTile(
        value: map["selected"],
        title: Text(map["hobby"]),
        onChanged: (v) {
          setState(() {
            this._hobbies[i]["selected"] = v;
          });
        },
      ));
    }
    return hobbyWidgets;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("信息登记系统")),
      body: Padding(
        padding: EdgeInsets.all(10),
        child: ListView(
          children: <Widget>[
            //姓名(单行输入框)
            TextField(
              decoration: InputDecoration(
                  border: OutlineInputBorder(), labelText: "用户姓名"),
              onChanged: (text) {
                setState(() {
                  this._userName = text;
                });
              },
            ),

            //性别(单选按钮组)
            Row(
              children: <Widget>[
                Text("男"),
                Radio(
                  value: 1,
                  onChanged: (sex) {
                    setState(() {
                      this._sex = sex;
                    });
                  },
                  groupValue: this._sex,
                ),
                SizedBox(width: 20),
                Text("女"),
                Radio(
                  value: 2,
                  onChanged: (sex) {
                    setState(() {
                      this._sex = sex;
                    });
                  },
                  groupValue: this._sex,
                )
              ],
            ),

            //兴趣爱好(多选按钮组)
            Column(
              children: this._getHobbyWidgets(),
            ),

            //备注信息(多行输入框)
            TextField(
              maxLines: 4,
              decoration: InputDecoration(
                hintText: "请输入备注信息",
                border: OutlineInputBorder(),
              ),
              onChanged: (v) {
                setState(() {
                  this._noteInfo = v;
                });
              },
            ),

            SizedBox(height: 20),

            //提交按钮(获取各种表单的信息)
            RaisedButton(
              color: Colors.blue,
              child: Text("提交"),
              onPressed: () {
                FocusScope.of(context).requestFocus(FocusNode());
                print("""
                ------
                   用户姓名:${this._userName},
                   性别:${this._sex}, ${this._sex == 1 ? "男" : "女"},
                   兴趣爱好:${this._hobbies},
                   备注信息:${this._noteInfo}
                """);
              },
            )
          ],
        ),
      ),
    );
  }
}

效果如下:

以上。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS小生活 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档