Flutter

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);
              },
            ),
          ),
        ],
      ),
    );
  }
}
上一篇 下一篇

猜你喜欢

热点阅读