【问题标题】:Why doesn't Switch in Flutter change value when I tap it but only on drag?为什么当我点击它时,Flutter 中的 Switch 不会改变值,而只是在拖动时?
【发布时间】:2019-11-14 20:58:27
【问题描述】:

当我尝试从示例/flutter_gallery 切换时,我可以点击它来更改值。

bool switchOn = false;

void _onSwitchChanged(bool value) {
  switchOn = false;
}

body: 
ListView(
 children: <Widget>[
    Row(
      children: <Widget>[
         Switch(
           onChanged: _onSwitchChanged,
           value: switchOn,
         ),
      ],
    ),
  ],
),       

【问题讨论】:

  • 请添加编码示例!
  • 你在examples/flutter_gallery来源中看不到他们是如何做到的?
  • 他们正在使用 setState(),我看不出这对开关行为有何影响
  • 好的,“开关”是什么意思?他们周围的标签是什么?
  • ListView(Row(Switch())

标签: user-interface flutter


【解决方案1】:

这个想法是,当您想要刷新屏幕时,您需要使用setState() 方法。所以实际上switchOn 的值实际上正在改变,但是这个改变并没有呈现在屏幕上,因为你没有使用setState() 你可以阅读更多关于它here

 bool switchOn = false;

   void _onSwitchChanged(bool value) {
      setState(() {
        switchOn = false;
      });
    }

body: ListView(
              children: <Widget>[
                Row(
                  children: <Widget>[
                    Switch(
                      onChanged: _onSwitchChanged,
                      value: switchOn,
                    ),
                  ],
                ),
              ],
            ),

【讨论】:

  • 这将在评论部分。这不是答案。
  • 是的,我只是没有足够的代表来做这件事,我很抱歉
【解决方案2】:

你应该更新状态来改变值

void _onSwitchChanged(bool value) {
   setState((){
      switchOn = false;
   });      
}

【讨论】:

  • 为什么 Switch 会随着 Drag 的改变而改变?
【解决方案3】:

当我为 web 构建时遇到了同样的问题,它变得难以调整开关,你需要一些方法来更新它,这样你就可以在开关上使用 AbsorbPointer 并通过 GestureDetector 处理更新或构建像这样的自定义开关(使代码连击):

class MSwitch extends StatefulWidget {
  final Function onChange;
  final bool value, round;
  final Color activeColor;
  final Color unActiveColor;
  final double width, height;
  MSwitch(
      {this.value,
      this.onChange,
      this.activeColor = Colors.green,
      this.unActiveColor = Colors.grey,
      this.width = 40,
      this.height = 20,
      this.round = true});
  @override
  _MSwitchState createState() => _MSwitchState();
}

class _MSwitchState extends State<MSwitch> {
  ScrollController controller = ScrollController();
  bool value;
  @override
  void initState() {
    value = widget.value ?? false;
    super.initState();
    if (value)
     Timer(Duration(milliseconds: 1), () {
        controller.animateTo(controller.position.maxScrollExtent,
          duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
     });
  }

  @override
  Widget build(BuildContext context) {
    double fullWidth = (widget.width - (widget.height / 2)) * 2;
    return GestureDetector(
        onTap: () {
          setState(() {
            value = !value;
          });
          if (widget.onChange != null) widget.onChange(value);

          if (controller.position.pixels == 0) {
            controller.animateTo(controller.position.maxScrollExtent,
                duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
          } else {
            controller.animateTo(0,
                duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
          }
        },
        child: ClipRRect(
          borderRadius: BorderRadius.circular(widget.height),
          child: Container(
            color: Colors.white,
            width: widget.width,
            height: widget.height,
            child: ScrollConfiguration(
              behavior: CustomBehavior(),
              child: ListView(
                controller: controller,
                shrinkWrap: true,
                scrollDirection: Axis.horizontal,
                physics: NeverScrollableScrollPhysics(),
                children: <Widget>[
                  Container(
                    width: fullWidth,
                    height: widget.height,
                    child: Stack(
                      alignment: Alignment.centerRight,
                      children: <Widget>[
                        Container(
                          margin: EdgeInsets.only(right: fullWidth / 2),
                          width: fullWidth / 2,
                          height: widget.height,
                          color: widget.activeColor,
                        ),
                        Container(
                          margin: EdgeInsets.only(left: fullWidth / 2),
                          width: fullWidth / 2,
                          height: widget.height,
                          color: widget.unActiveColor,
                        ),
                        Container(
                          margin: EdgeInsets.only(
                              right: (fullWidth / 2) - (widget.height / 2)),
                          width: widget.height,
                          height: widget.height,
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(
                                  widget.round ? widget.height : 0),
                              color: Colors.white),
                        )
                      ],
                    ),
                  )
                ],
              ),
            ),
          ),
        ));
  }
}
class CustomBehavior extends ScrollBehavior {
  @override
  Widget buildViewportChrome(
      BuildContext context, Widget child, AxisDirection axisDirection) {
    return child;
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-01
    • 2023-02-09
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2019-08-10
    • 2023-04-03
    • 1970-01-01
    相关资源
    最近更新 更多