flutter:Switch回调触发的条件和点击改变状态的实现
2018-11-12 本文已影响1268人
谢伟浩
1. Switch的OnChanged触发条件
今天使用Switch发现,Switch打开时为触发Onchanged,而关闭时不会触发,代码如下:
new Switch(
value: _value, //这里初始值为false
onChanged: (b) {
print(b); //发现只会打印true
//TODO 回调任务
},
我们可以猜想:拖动Switch后的状态要与Switch中的value不一样时,OnChanged才会被回调。在上述代码中添加_value = b, 为了更新Switch的value值还应使用setState方法。代码如下修改,证实我们的猜想是正确的。
new Switch(
value: _value,
onChanged: (b) {
setState(() { //要把改变后的值更新到switch中的value中去,手动复原时才会触发
_value = b;
print(b); //true,false交替打印
});
//TODO 回调任务
},
2. 实现Switch点击改变状态
这个问题简单,只需在Switch外面嵌套一个Container即可。
我们可以在Switch的父类RenderToggleable中找到原因:
void _handleTap() {
if (!isInteractive)
return;
switch (value) {
case false:
onChanged(true);
break;
case true:
onChanged(tristate ? null : false);
break;
default: // case null:
onChanged(false);
break;
}
sendSemanticsEvent(const TapSemanticEvent());
}
最后,附上一个Text + Switch的代码:
class SwitchDetail extends StatefulWidget {
String title;
bool initValue;
ValueChanged<bool> onChanged;
SwitchDetail(this.title, {this.initValue = true, this.onChanged});
_SwitchDetailState state;
@override
State<StatefulWidget> createState() {
state = _SwitchDetailState();
return state;
}
get value {
return state.value;
}
set value(bool b) {
state.value = b;
}
}
class _SwitchDetailState extends State<SwitchDetail> {
bool _value;
get value {
return _value;
}
set value(bool b) {
setState(() {
_value = b;
});
//只更新自身,不触发widget.onChanged
}
@override
void initState() {
super.initState();
_value = widget.initValue;
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
padding: EdgeInsets.only(left:18.0, right: 18.0),
height: 48.0,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Expanded(child: new Text(widget.title)),
new Container( //嵌套一个Container使点击Switch时也会改变其状态
child: new Switch(
value: _value,
onChanged: (b) {
setState(() { //要把改变后的值更新到switch中的value中去,手动复原时才会触发
_value = b;
});
widget.onChanged(b);
},
),
),
],
),
);
}
}