单选框和复选框
Material 组件库中提供了Material风格的单选开关Switch和复选框Checkbox,虽然它们都是继承自StatefulWidget,但它们本身不会保存当前选中状态,选中状态都是由父组件来管理的。当Switch或Checkbox被点击时,会触发它们的onChanged回调,我们可以在此回调中处理选中状态改变逻辑。
常见属性
Radio单选框
属性 | 说明 |
---|---|
value | 单选的值 |
onChanged | 改变时触发 |
activeColor | 选中的颜色、背景颜色 |
groupValue | 选择组的值 |
代码示例:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: "Radio",
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int sex = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Radio")),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("大:"),
Radio(
value: 1,
groupValue: this.sex,
onChanged: (value) {
setState(() {
this.sex = value;
});
},
),
SizedBox(width: 20),
Text("小:"),
Radio(
value: 2,
groupValue: this.sex,
onChanged: (value) {
setState(() {
this.sex = value;
});
},
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("你选择的是${this.sex == 1 ? "大" : "小"}")
],
)
],
),
);
}
}
RadioListTile单选框
属性 | 说明 |
---|---|
value | true 或者 false |
onChanged | 改变的时候触发的事件 |
activeColor | 选中的颜色、背景颜色 |
title | 标题 |
subtitle | 二级标题 |
secondary | 配置图标或者图片 |
groupValue | 选择组的值 |
代码如下:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: "RadioListTile",
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int sex = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("我的app")),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RadioListTile(
value: 1,
onChanged: (value) {
setState(() {
this.sex = value;
});
},
groupValue: this.sex,
title: Text("一级标题"),
subtitle: Text("二级标题"),
secondary: Icon(Icons.camera),
selected: this.sex == 1,
),
],
),
);
}
}
Checkbox 复选框
属性 | 说明 |
---|---|
value | 是否选中此复选框 |
onChanged | 监听,当复选框的值应该更改时调用 |
tristate | 默认false,如果为true,复选框的值可以为true、false或null |
activeColor | 选中此复选框时要使用的颜色 |
checkColor | 选中此复选框时用于复选图标的颜色 |
materialTapTargetSize | 配置tap目标的最小大小 |
代码:
Checkbox(
value: this.valueb,
onChanged: (bool value) {
setState(() {
this.valueb = value;
});
},
CheckboxListTile 复选框
属性 | 说明 |
---|---|
value | 是否选中此复选框 |
onChanged | 监听,当复选框的值应该更改时调用 |
activeColor | 选中此复选框时要使用的颜色 |
title | 列表主标题 |
subtitle | 列表副标题 |
isThreeLine | 默认false |
dense | 此列表平铺是否是垂直密集列表的一部分 |
secondary | 显示在复选框前面的小部件 |
selected | 选中后文字高亮,默认false |
controlAffinity | 控件相对于文本的位置,默认 ListTileControlAffinity.platform |
代码:
CheckboxListTile(
secondary: const Icon(Icons.alarm_on),
title: const Text('每天6:10 响铃'),
subtitle: Text('12小时58分钟后响铃'),
value: this.valued,
onChanged: (bool value) {
setState(() {
this.valued = value;
});
},
下面以一个例子说明状态的维护:
以下代码中,由于需要维护Switch和Checkbox的选中状态,所以SwitchAndCheckBoxTestRoute继承自StatefulWidget 。在其build方法中分别构建了一个Switch和Checkbox,初始状态都为选中状态,当用户点击时,会将状态置反,然后回调用setState()通知Flutter framework重新构建UI
class SwitchAndCheckBoxTestRoute extends StatefulWidget {
@override
_SwitchAndCheckBoxTestRouteState createState() => new _SwitchAndCheckBoxTestRouteState();
}
class _SwitchAndCheckBoxTestRouteState extends State<SwitchAndCheckBoxTestRoute> {
bool _switchSelected=true; //维护单选开关状态
bool _checkboxSelected=true;//维护复选框状态
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Switch(
value: _switchSelected,//当前状态
onChanged:(value){
//重新构建页面
setState(() {
_switchSelected=value;
});
},
),
Checkbox(
value: _checkboxSelected,
activeColor: Colors.red, //选中时的颜色
onChanged:(value){
setState(() {
_checkboxSelected=value;
});
} ,
)
],
);
}
}
总结
通过Switch和Checkbox我们可以看到,虽然它们本身是与状态(是否选中)关联的,但它们却不是自己来维护状态,而是需要父组件来管理状态,然后当用户点击时,再通过事件通知给父组件,这样是合理的,因为Switch和Checkbox是否选中本就和用户数据关联,而这些用户数据也不可能是它们的私有状态。我们在自定义组件时也应该思考一下哪种状态的管理方式最为合理。