一.Flutter 中常见的表单
TextField 单行文本框,TextField 多行文本框、CheckBox、Radio、Switch
CheckboxListTile、RadioListTile、SwitchListTile、Slide
二.TextField 文本框组件
属性 |
描述 |
maxLines |
设置此参数可以把文本框改为多行文本框 |
onChanged |
文本框改变的时候触发的事件 |
decoration |
hintText 类似 html 中的 placeholder; border 配置文本框边框 OutlineInputBorder 配合使用; labelText lable 的名称; labelStyle 配置 lable 的样式 |
obscureTex |
把文本框框改为密码框 |
controller |
controller 结合TextEditingController()可以配置表单默认显示的内容 |
TextField(
decoration: InputDecoration(
hintText: "密码框",
border: OutlineInputBorder()
),
controller: controller,
maxLength: 30,//最大长度,设置此项会让TextField右下角有一个输入数量的统计字符串
maxLines: 1,//最大行数
autocorrect: true,//是否自动更正
autofocus: true,//是否自动对焦
obscureText: true,//是否是密码
textAlign: TextAlign.center,//文本对齐方式
style: TextStyle(
fontSize: 30.0, color:Colors.blue
),//输入文本的样式
inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],//允许的输入格式
onChanged: (text) {//内容改变的回调
print('change $text');
},
onSubmitted: (text) {//内容提交(按回车)的回调
print('submit $text');
},
enabled: true,//是否禁用
)
其中InputDecoration装饰器
属性 |
描述 |
icon |
位于装饰器外部和输入框前面的图片 |
labelText |
用于描述输入框,例如这个输入框是用来输入用户名还是密码的,当输入框获取焦点时默认会浮动到上方 |
labelStyle |
控制labelText的样式,接收一个TextStyle类型的值 |
helperText |
辅助文本,位于输入框下方,如果errorText不为空的话,则helperText不会显示 |
helperStyle |
helperText的样式 |
hintText |
提示文本,位于输入框内部 |
hintStyle |
hintText的样式 |
hintMaxLines |
提示信息最大行数 |
errorText |
错误信息提示 |
errorStyle |
errorText的样式 |
errorMaxLines |
errorText最大行数 |
hasFloatingPlaceholder = true |
labelText是否浮动,默认为true,修改为false则labelText在输入框获取焦点时不会浮动且不显示 |
isDense |
改变输入框是否为密集型,默认为false,修改为true时,图标及间距会变小 |
contentPadding |
内间距 |
prefixIcon |
位于输入框内部起始位置的图标。 |
prefix |
预先填充的Widget,跟prefixText同时只能出现一个 |
prefixText |
预填充的文本,例如手机号前面预先加上区号等 |
prefixStyle |
prefixText的样式 |
suffixIcon |
位于输入框后面的图片,例如一般输入框后面会有个眼睛,控制输入内容是否明文 |
suffix |
位于输入框尾部的控件,同样的不能和suffixText同时使用 |
suffixText |
位于尾部的填充文字 |
suffixStyle |
suffixText的样式 |
counter |
位于输入框右下方的小控件,不能和counterText同时使用 |
counterText |
位于右下方显示的文本,常用于显示输入的字符数量 |
counterStyle |
counterText的样式 |
filled |
如果为true,则输入使用fillColor指定的颜色填充 |
fillColor |
相当于输入框的背景颜色 |
errorBorder |
errorText不为空,输入框没有焦点时要显示的边框 |
focusedBorder |
输入框有焦点时的边框,如果errorText不为空的话,该属性无效 |
focusedErrorBorder |
errorText不为空时,输入框有焦点时的边框 |
disabledBorder |
输入框禁用时显示的边框,如果errorText不为空的话,该属性无效 |
enabledBorder |
输入框可用时显示的边框,如果errorText不为空的话,该属性无效 |
border |
正常情况下的border |
enabled = true |
输入框是否可用 |
semanticCounterText |
|
alignLabelWithHint |
|
image
import 'package:flutter/material.dart';
class ValuePage extends StatefulWidget {
ValuePage({Key key}) : super(key: key);
@override
_ValuePageState createState() => _ValuePageState();
}
class _ValuePageState extends State<ValuePage> {
final controller = new TextEditingController();
var _password;//不需要初始值情况,可以不用controller,直接定义一个变量
@override
void initState() {
super.initState();
controller.text = '初始值';
}
@override
Widget build(BuildContext context) {
// controller.addListener(() {
// print('input${controller.text}');
// });
return Scaffold(
appBar: AppBar(title: Text('TextFiled Demo')),
body: Padding(
padding: EdgeInsets.all(10),
child: Column(children: <Widget>[
TextField(controller: controller),
SizedBox(height: 10),
TextField(
obscureText: true,
decoration: InputDecoration(hintText: '请输入密码'),
onChanged: (text) {
setState(() {
_password = text;
});
},
),
SizedBox(height: 10),
Row(children: [
Expanded(
child: RaisedButton(
child: Text('获取用户名'),
onPressed: () {
print('get:${controller.text}');
},
color: Colors.blue,
textColor: Colors.white,
))
]),
Container(
width: double.infinity,
child: RaisedButton(
child: Text('获取密码'),
onPressed: () {
print('get:${this._password}');
},
color: Colors.blue,
textColor: Colors.white,
))
])));
}
}
三、Checkbox、CheckboxListTile 多选框
CheckboxListTile放在row里面会报错,版本flutter1.17.0
属性 |
描述 |
value |
true 或者 false |
onChanged |
改变的时候触发的事件 |
activeColor |
选中的颜色、背景颜色 |
checkColor |
选中的颜色、Checkbox 里面对号的颜色 |
属性 |
描述 |
value |
true 或者 false |
onChanged |
改变的时候触发的事件 |
title |
标题 |
subtitle |
二级标题 |
activeColor |
选中的颜色、背景颜色 |
secondary |
配置图标或者图片 |
selected |
选中的时候文字颜色是否跟着改变 |
image
import 'package:flutter/material.dart';
class CheckboxPage extends StatefulWidget {
CheckboxPage({Key key}) : super(key: key);
@override
_CheckboxPageState createState() => _CheckboxPageState();
}
class _CheckboxPageState extends State<CheckboxPage> {
String sex = 'isMale';
bool _flag2 = true;
bool _flag3 = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('checkbox demo')),
body: ListView(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(children: <Widget>[
Text('男:'),
Checkbox(
value: sex=='isFemale',
onChanged: (value) {
setState(() {
this.sex = value?'isFemale':'isMale';
});
})
]),
Row(children: <Widget>[
Text('女:'),
Checkbox(
value: sex=='isMale',
onChanged: (value) {
setState(() {
this.sex = value?'isMale':'isFemale';
});
})
]),
]
),
Divider(),
Container(
child:CheckboxListTile(
value: this._flag2,
title: Text("标题"),
// secondary: Icon(Icons.headset_mic),
selected: this._flag2,
onChanged: (value) {
setState(() {
this._flag2 = value;
});
},
)
),
Divider(),
Container(
child:CheckboxListTile(
value: this._flag3,
title: Text("标题"),
subtitle: Text("这是二级标题"),
secondary: Icon(Icons.headset_mic),
selected: this._flag3,
onChanged: (value) {
setState(() {
this._flag3 = value;
});
},
)
)
]
)
);
}
}
四、Radio、RadioListTile 单选按钮
属性 |
描述 |
value |
单选的值 |
onChanged |
改变时触发 |
activeColor |
选中的颜色、背景颜色 |
groupValue |
选择组的值 |
- RadioListTile组件常用的属性:
RadioListTile放在row里面会报错,版本flutter1.17.0
属性 |
描述 |
value |
true 或者 false |
onChanged |
改变的时候触发的事件 |
activeColor |
选中的颜色、背景颜色 |
title |
标题 |
subtitle |
二级标题 |
secondary |
配置图标或者图片 |
groupValue |
选择组的值 |
isThreeLine |
是否显示三行 |
dense |
垂直密集排列 |
selected |
选中的时候文字颜色是否跟着改变 |
ControlAffinity |
控件相对于文本的位置 1.ListTileControlAffinity.leading:复选框在前面 2.ListTileControlAffinity.trailing: 复选框在后面,secondary在前面 3.ListTileControlAffinity.platform:以当前平台的典型方式将控件相对于文本定位,并将辅助小部件放在另一侧。 |
image
import 'package:flutter/material.dart';
class RadioPage extends StatefulWidget {
RadioPage({Key key}) : super(key: key);
@override
_RadioPageState createState() => _RadioPageState();
}
class _RadioPageState extends State<RadioPage> {
var _sex = 1;
var _grade = 1;
var _class = 1;
List gradeList = [
{'id': 1, 'value': '一年级'},
{'id': 2, 'value': '二年级'},
{'id': 3, 'value': '三年级'},
{'id': 4, 'value': '四年级'},
{'id': 5, 'value': '五年级'},
{'id': 6, 'value': '六年级'}
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Radio Demo')),
body: Container(
padding: EdgeInsets.all(10),
child: Column(children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text('性别:'),
Row(children: <Widget>[
Text('男'),
Radio(
value: 1,
groupValue: this._sex,
onChanged: (value) {
setState(() {
this._sex = value;
});
})
]),
Row(children: <Widget>[
Text('女'),
Radio(
value: 2,
groupValue: this._sex,
onChanged: (value) {
setState(() {
this._sex = value;
});
})
])
]),
Divider(),
Row(children: <Widget>[
Text('年级:'),
Expanded(
flex: 1,
child: Wrap(
children: gradeList.map((item) {
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(item['value']),
Radio(
value: item['id'],
groupValue: this._grade,
onChanged: (value) {
setState(() {
this._grade = value;
});
}
)
]);
}).toList()),
)
]),
Divider(),
Container(
child: RadioListTile(
value: 1,
groupValue: this._class,
title: Text('班级'),
controlAffinity: ListTileControlAffinity.trailing,
onChanged: (value) {
setState(() {
this._class = value;
});
},
))
])));
}
}
五、开关 Switch
属性 |
描述 |
value |
单选的值 |
onChanged |
改变时触发 |
activeColor |
选中的颜色、背景颜色 |
image
import 'package:flutter/material.dart';
class SwitchPage extends StatefulWidget {
SwitchPage({Key key}) : super(key: key);
@override
_SwitchPageState createState() => _SwitchPageState();
}
class _SwitchPageState extends State<SwitchPage> {
var _flag=false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Switch Demo')),
body: Column(children: <Widget>[
Row(
children: <Widget>[
Text('是否通过'),
Switch(
value: this._flag,
onChanged: (value) {
setState(() {
this._flag = value;
});
}
)
]
)
]
)
);
}
}
随便写了个demo 没搞明白那个(爱好和选项)(年级和选项)怎么靠头部对齐
image
import 'package:flutter/material.dart';
class FormPage extends StatefulWidget {
FormPage({Key key}) : super(key: key);
@override
_FormPageState createState() => _FormPageState();
}
class _FormPageState extends State<FormPage> {
int _sex;
String _name;
bool _email = false;
String _info = '';
int _grade = 1;
List _gradeList = [
{'id': 1, 'value': '一年级'},
{'id': 2, 'value': '二年级'},
{'id': 3, 'value': '三年级'},
{'id': 4, 'value': '四年级'},
{'id': 5, 'value': '五年级'},
{'id': 6, 'value': '六年级'}
];
List _hobbyList = [
{'id': 1, 'value': '吃饭', 'check': true},
{'id': 2, 'value': '睡觉', 'check': false},
{'id': 3, 'value': '学习', 'check': false},
{'id': 4, 'value': '打豆豆', 'check': true}
];
void _changeSex(value) {
setState(() {
this._sex = value;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('学员信息登记系统')),
body: Padding(
padding: EdgeInsets.all(10.0),
child: ListView(children: <Widget>[
TextField(
decoration: InputDecoration(hintText: '请输入用户名'),
onChanged: (v) {
setState(() {
this._name = v;
});
},
),
Row(children: <Widget>[
Text('性别:',
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
SizedBox(width: 10.0),
Row(children: <Widget>[
Text('男'),
Radio(
value: 1,
groupValue: this._sex,
onChanged: this._changeSex,
)
]),
Row(children: <Widget>[
Text('女'),
Radio(
value: 2,
groupValue: this._sex,
onChanged: this._changeSex,
)
])
]),
Row(children: <Widget>[
Text('年级:'),
Expanded(
flex: 1,
child: Wrap(
children: _gradeList.map((item) {
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(item['value']),
Radio(
value: item['id'],
groupValue: this._grade,
onChanged: (value) {
setState(() {
this._grade = value;
});
})
]);
}).toList()),
)
]),
Row(
children: <Widget>[
Text('爱好:',
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
SizedBox(width: 10.0),
Expanded(
flex: 1,
child: Wrap(
children: _hobbyList.map((item) {
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(item['value']),
Checkbox(
value: item['check'],
onChanged: (value) {
setState(() {
item['check'] = value;
});
})
]);
}).toList()))
],
),
Row(children: <Widget>[
Text('已注册学院邮箱:'),
Switch(
value: this._email,
onChanged: (v) {
setState(() {
this._email = v;
});
}),
]),
TextField(
maxLines: 3,
decoration: InputDecoration(
hintText: '描述本学期目标', border: OutlineInputBorder()),
onChanged: (value) {
setState(() {
this._info = value;
});
},
),
SizedBox(height: 40),
OutlineButton(
child: Text('注册'),
onPressed: () {
var use = {};
use['name'] = _name;
use['sex'] = _sex == 1 ? '男' : _sex == 2 ? '女' : null;
use['grade'] = _grade;
use['hobby'] = _hobbyList.where((w) => w['check']);
use['email'] = _email;
use['info'] = _info;
print(use);
},
)
])));
}
}
网友评论