在前面的文章中我们学习了Flutter中事件的处理,包括组件的单击、双击、长按、滑动等。想必大家多其已经有了一定的认识。
那么,这节我们主要介绍下Flutter中输入和选择组件的用法。
TextField
顾名思义文本输入框,类似于Ios中的UITextField和Android中的EditText。主要是为用户提供输入文本提供方便。相信大家在原生客户端上都用过这个功能,就不在做具体介绍了,接下来还是具体介绍下Flutter中TextField的用法。
TextField的构造方法:
代码语言:javascript复制const TextField({
Key key,
this.controller,//控制器,控制TextField文字
this.focusNode,
this.decoration: const InputDecoration(),//输入器装饰
TextInputType keyboardType: TextInputType.text,//输入的类型
this.style,
this.textAlign: TextAlign.start,//对齐方式
this.autofocus: false,
this.obscureText: false,//是否隐藏输入
this.autocorrect: true,
this.maxLines: 1,
this.maxLength,
this.maxLengthEnforced: true,
this.onChanged,//文字改变触发
this.onSubmitted,//文字提交触发(键盘按键)
this.inputFormatters,
})
先来试试最基本的TextField
代码语言:javascript复制import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("TextField"),
),
body: new TextField());
}
}
看下效果
我们增加一个keyboardType属性,把keyboardType设置为TextInputType.number
可以看到每次我们让TextField获得焦点的时候弹出的键盘就变成了数字优先了。
当然,我们也可以为输入框做一些其他的效果,如提示文字,icon、标签文字等。
代码语言:javascript复制new TextField(keyboardType: TextInputType.number,
decoration: new InputDecoration(
contentPadding: const EdgeInsets.only(top: 10.0),
icon: new Icon(Icons.phone),
labelText: "请输入你的手机号",
helperText: "注册时填写的手机号码"),
autofocus: false,
))
看下效果
我们给上面的代码新增decoration属性,可以发现当我们的TextField获得焦点时,图标会自动变色,提示文字会自动上移。
接下来,我们来看下onChanged和onSubmitted。onChanged是每次输入框内每次文字变更触发的回调,onSubmitted是用户提交而触发的回调。
在前面代码的基础上新增如下代码:
代码语言:javascript复制onChanged: (String str){
print("用户输入变更:$str");
},
onSubmitted: (String str){
print("用户提交:$str");
},
每当用户改变输入框内的文字,都会在控制台输出现在的字符串 当用户点击提交按钮(输入法回车键)
再来看下效果:
控制台输出:
代码语言:javascript复制
I/flutter (31747): 用户输入变更:1
I/flutter (31747): 用户输入变更:12
I/flutter (31747): 用户输入变更:123
I/flutter (31747): 用户输入变更:1234
I/flutter (31747): 用户输入变更:12345
I/flutter (31747): 用户输入变更:123456
I/flutter (31747): 用户提交:123456
看了这么多的基础用法,我们还是来看个例子把。
当用户输入 用户名flyou,密码是admin时,提示登录成功,当用户名密码不是此值时提示登录失败。
在这里,我们需要简单介绍下SnackBar
使用 Scaffold.of(context).showSnackBar()即可显示SnackBar,大家在这里不需要了解太多,以后会具体介绍的。
我们还是来看下具体的代码吧:
代码语言:javascript复制import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
//用户名输入框的控制器
TextEditingController _userNameController = new TextEditingController();
//密码输入框的控制器
TextEditingController _userPasswordController = new TextEditingController();
void onTextClear() {
setState(() {
_userNameController.text = "";
_userPasswordController.text = "";
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("TextField"),
),
body: new Column(
children: <Widget>[
new TextField(
controller: _userNameController,
decoration: new InputDecoration(
contentPadding: const EdgeInsets.only(top: 10.0),
icon: new Icon(Icons.perm_identity),
labelText: "请输入用户名",
helperText: "注册时填写的名字"),
),
new TextField(
controller: _userPasswordController,
decoration: new InputDecoration(
contentPadding: const EdgeInsets.only(top: 10.0),
icon: new Icon(Icons.lock),
labelText: "请输入密码",
helperText: "登录密码"),
obscureText: true,
),
new Builder(builder: (BuildContext context) {
//监听RaisedButton的点击事件,并做相应的处理
return new RaisedButton(
onPressed: () {
if (_userNameController.text.toString() == 'flyou' &&
_userPasswordController.text.toString() == 'admin') {
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text("登录成功")));
} else {
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text("登录失败,用户名密码有误")));
}
onTextClear();
},
color: Colors.blue,
highlightColor: Colors.lightBlueAccent,
disabledColor: Colors.lightBlueAccent,
child: new Text(
"登录",
style: new TextStyle(color: Colors.white),
));
})
],
));
}
}
在布局上,我们使用一个Column包含了两个TextField和一个RaisedButton。
在逻辑上,每当我们点击下面的按钮都会判断用户名密码是否是flyou和admin,并且使用控制器清空已经输入的用户名和密码。
如果用户输入的用户名等于flyou,密码等于admin则提示“登录成功”,否则提示“登录失败,用户名密码有误”。
代码的逻辑很简单,结合前面的StatefulWidget的用法,看起来也是非常简单的。关于TextField的其他用法就不在一一介绍了,有兴趣的小伙伴可以自己尝试下。
下面我们来你看下Checkbox
Checkbox
Checkbox,没错就是我们常用的复选框,具体的用法也很简单的
构造方法:
代码语言:javascript复制const Checkbox({
Key key,
@required this.value,//当前值,是否选中
@required this.onChanged,//选中变更监听
this.activeColor,//选中时的颜色
})
直接看代码看用法:
代码语言:javascript复制import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
var _isChecked = true;
onCheckChange(bool isChecked) {
setState(() {
_isChecked = isChecked;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("CheckBox"),
),
body: new Center(
child: new Checkbox(value: _isChecked, onChanged: onCheckChange),
),
);
}
}
我们在屏幕的正中央放置了一个Checkbox,每当用户点击时就变更选中的状态。
代码很简单,不再做具体介绍了
Radio
没错Radio就是我们常用的单选框的意思,通常Radio都是成组出现的,在一组Radio中,只能有一个选中的。
构造方法:
代码语言:javascript复制const Radio({
Key key,
@required this.value,
@required this.groupValue,
@required this.onChanged,
this.activeColor
})
构造方法和上面的Checkbox基本类似,只不过比上面的Checkbox多了一个groupValue参数,当然这个参数就是用来控制分组的。
还是来看代码:
代码语言:javascript复制import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
int radioValue=0;
void handleRadioValueChanged(int value) {
setState(() {
radioValue = value;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("CheckBox"),
),
body: new Center(
child: new Column(
children: <Widget>[
new Radio(
value: 0,
groupValue: radioValue,
onChanged: handleRadioValueChanged),
new Radio(
value: 1,
groupValue:radioValue,
onChanged: handleRadioValueChanged),
new Radio(
value: 2,
groupValue: radioValue,
onChanged: handleRadioValueChanged),
new Radio(
value: 3,
groupValue: radioValue,
onChanged: handleRadioValueChanged)
],
)),
);
}
}
我们在Column放了4个Radio,每当点击Radio都会触发handleRadioValueChanged方法来更改当前选中的Radio并且更新选中状态。
看下效果:
Switch
Switch翻译过来就是开关的意思,就是控制开关。和Ios和Android中的Switch组件类似
构造方法如下
代码语言:javascript复制const Switch({
Key key,
@required this.value,
@required this.onChanged,
this.activeColor,
this.activeTrackColor,
this.inactiveThumbColor,
this.inactiveTrackColor,
this.activeThumbImage,
this.inactiveThumbImage
})
已经很简单,只不过多了几个参数用来控制打开和关闭时的颜色或者图片。
还是来看下基本的用法:
代码语言:javascript复制import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
var _isChecked = true;
onSwitchChange(bool isChecked) {
setState(() {
print(isChecked);
_isChecked = isChecked;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Switch"),
),
body: new Center(
child: new Switch(value: _isChecked, onChanged: onSwitchChange),
),
);
}
}
看了上面的代码是不是觉得跟CheckBox基本上一模一样呢?
Slider
Slider滑块组件,也类似于进度条组件,用法依旧很简单。
代码语言:javascript复制const Slider({
Key key,
@required this.value,
@required this.onChanged,
this.min: 0.0,//最小值
this.max: 1.0,//最小值
this.divisions,
this.label,//标志
this.activeColor,
this.inactiveColor,
this.thumbOpenAtMin: false,
})
由于很简单就直接给大家看代码了。
代码语言:javascript复制import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
double currentPosition = 66.0;
onSliderChange(double position) {
setState(() {
print(position);
currentPosition = position;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Slider"),
),
body: new Center(
child: new Slider(
label: "进度",
min: 0.0,
max: 100.0,
value: currentPosition,
onChanged: onSliderChange,
),
),
);
}
}
我们设置slider的默认进度为66,每当用户滑动滑块时根据用户的滑动改变滑块的位置。
更多相关Widget
在上面我们分别介绍了,CheckBox、Radio、Switch、的用法,但是这些组件一般不是单独使用的,一般会和Text、Icon或者其他的Widget结合使用。
当然Flutter中为我们内置了多个相关的Widget,例如:
CheckboxListTile、RadioListTile、SwitchListTile,当然这些Widget的用法类似于前面我们说过的ListTitle,只不过在多了一个上面的Widget而已,当然用法也是非常简单的。
我们来看下CheckboxListTile
代码语言:javascript复制import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
var _isChecked = true;
onCheckChange(bool isChecked) {
setState(() {
print(isChecked);
_isChecked = isChecked;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("CheckedBoxListTitle"),
),
body: new CheckboxListTile(
value: _isChecked,
onChanged: onCheckChange,
secondary: new Icon(Icons.update,color: Colors.blueAccent,),
title: new Text("新版本自动下载"),
subtitle: new Text("仅在WiFi环境下生效"),
),
);
}
}
同样的每当我们点击CheckBox或者这个CheckboxListTile都会触发CheckBox的相应操作,去改变Checkbox的状态。
RadioListTile和SwitchListTile的用法基本相同,这里就不在具体介绍了,大家可以在下面试一下如何使用。
小结
- 可以根据TextField的相关属性来完成特定的输入需求
- CheckBox、Radio、Switch是开发中常用的选择组件
- Slider滑块组件,可以满足用户对进度的精确控制
- CheckboxListTile、RadioListTile和SwitchListTile是对相应组件的封装
试一试
根据我们以前学过的东东完成下图效果
最近大家都在说公众号上阅读不方便,会把文章同步到网站上(http://flutter.link),点击阅读原文即可查看。
当然,有什么问题也欢迎大家在后台留言,我会在看到的第一时间回复大家的
我怀疑这个是个坏掉的二维码,分享到朋友圈试试?