【问题标题】:setState called during build in flutter在颤振中构建期间调用的 setState
【发布时间】:2020-06-21 11:52:43
【问题描述】:

我正在尝试制作一个颤动的应用程序,我在这里要做的就是在用户更改 LiteRollingSwitch 时将 bool isSwitched 更改为 true 或 false。 (我使用了这个https://pub.dev/packages/lite_rolling_switch#-readme-tab- 库)。在 onchage 方法中,如果我创建“setstate”,它会给我一个如下所示的错误。

但我需要将 isSwitched 状态更改为 true 或 false 取决于用户的选择;它允许用户模糊图像或取消模糊图像。有人有解决这个问题的想法吗?

class UploadPhoto extends StatefulWidget {
      @override
      _UploadPhotoState createState() => _UploadPhotoState();
    }

class _UploadPhotoState extends State<UploadPhoto> {
  bool isSwitched = false;
  File _image;

  // select image via either folder of camera
  Future getImageFromGallery() async {
    PickedFile image =
        await ImagePicker().getImage(source: ImageSource.gallery);

    setState(() {
      _image = File(image.path);
    });
  }

  Future getImageFromCamera() async {
    PickedFile image = await ImagePicker().getImage(source: ImageSource.camera);

    setState(() {
      _image = File(image.path);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SafeArea(
      child: Stack(
        children: <Widget>[
          Container(...),
          Container(
            child: Center(
              child: SingleChildScrollView(
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Column(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: <Widget>[
                      Container(
                        child: _image != null
                            ? Center(
                                    Transform.scale(
                                  scale: 0.8,
                                  child: LiteRollingSwitch(
                                    value: isSwitched,
                                    textOn: 'On',
                                    textOff: 'Off',
                                    colorOn: Hexcolor("#8CC63E"),
                                    colorOff: Colors.blueGrey,
                                    iconOn: Icons.done,
                                    iconOff: Icons.remove_circle_outline,
                                    onChanged: (value) {
//                                      isSwitched = value;
                                      setState(() {
                                        isSwitched = value;
                                      });
                                    },
                                  ),
                                ),

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    好消息:这不是你的错。

    坏消息:你必须修改他们的代码或等到他们改变它。

    我在 github here 上创建了一个拉取请求。但是他们似乎没有对问题做出响应,因此您最好更改他们的代码。

    所以同时,如果你想使用这个包,你应该更改 lite_rolling_switch.dart 中的代码(通过转到 ~/.pub-cache/hosted/pub.dartlang.org/lite_rolling_switch- 0.1.1/lib/lite_rolling_switch.dart 或者你可以 Ctrl + 左键单击文件中的 LiteRollingSwitch 类)到以下内容:

    library lite_rolling_switch;
    
    import 'package:flutter/material.dart';
    import 'dart:ui';
    import 'dart:math';
    
    /// Customable and attractive Switch button.
    /// Currently, you can't change the widget
    /// width and height properties.
    ///
    /// As well as the classical Switch Widget
    /// from flutter material, the following
    /// arguments are required:
    ///
    /// * [value] determines whether this switch is on or off.
    /// * [onChanged] is called when the user toggles the switch on or off.
    ///
    /// If you don't set these arguments you would
    /// experiment errors related to animationController
    /// states or any other undesirable behavior, please
    /// don't forget to set them.
    ///
    class LiteRollingSwitch extends StatefulWidget {
      @required
      final bool value;
      @required
      final Function(bool) onChanged;
      final String textOff;
      final String textOn;
      final Color colorOn;
      final Color colorOff;
      final double textSize;
      final Duration animationDuration;
      final IconData iconOn;
      final IconData iconOff;
      final Function onTap;
      final Function onDoubleTap;
      final Function onSwipe;
    
      LiteRollingSwitch(
          {this.value = false,
          this.textOff = "Off",
          this.textOn = "On",
          this.textSize = 14.0,
          this.colorOn = Colors.green,
          this.colorOff = Colors.red,
          this.iconOff = Icons.flag,
          this.iconOn = Icons.check,
          this.animationDuration = const Duration(milliseconds: 600),
          this.onTap,
          this.onDoubleTap,
          this.onSwipe,
          this.onChanged});
    
      @override
      _RollingSwitchState createState() => _RollingSwitchState();
    }
    
    class _RollingSwitchState extends State<LiteRollingSwitch>
        with SingleTickerProviderStateMixin {
      AnimationController animationController;
      Animation<double> animation;
      double value = 0.0;
    
      bool turnState;
    
      @override
      void dispose() {
        animationController.dispose();
        super.dispose();
      }
    
      @override
      void initState() {
        super.initState();
        animationController = AnimationController(
            vsync: this,
            lowerBound: 0.0,
            upperBound: 1.0,
            duration: widget.animationDuration);
        animation =
            CurvedAnimation(parent: animationController, curve: Curves.easeInOut);
        animationController.addListener(() {
          setState(() {
            value = animation.value;
          });
        });
        turnState = widget.value;
        if (turnState) {
          animationController.animateTo(1, duration: Duration(seconds: 0));
        }
      }
    
      @override
      Widget build(BuildContext context) {
        Color transitionColor = Color.lerp(widget.colorOff, widget.colorOn, value);
    
        return GestureDetector(
          onDoubleTap: () {
            _action();
            if (widget.onDoubleTap != null) widget.onDoubleTap();
          },
          onTap: () {
            _action();
            if (widget.onTap != null) widget.onTap();
          },
          onPanEnd: (details) {
            _action();
            if (widget.onSwipe != null) widget.onSwipe();
            //widget.onSwipe();
          },
          child: Container(
            padding: EdgeInsets.all(5),
            width: 130,
            decoration: BoxDecoration(
                color: transitionColor, borderRadius: BorderRadius.circular(50)),
            child: Stack(
              children: <Widget>[
                Transform.translate(
                  offset: Offset(10 * value, 0), //original
                  child: Opacity(
                    opacity: (1 - value).clamp(0.0, 1.0),
                    child: Container(
                      padding: EdgeInsets.only(right: 10),
                      alignment: Alignment.centerRight,
                      height: 40,
                      child: Text(
                        widget.textOff,
                        style: TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                            fontSize: widget.textSize),
                      ),
                    ),
                  ),
                ),
                Transform.translate(
                  offset: Offset(10 * (1 - value), 0), //original
                  child: Opacity(
                    opacity: value.clamp(0.0, 1.0),
                    child: Container(
                      padding: EdgeInsets.only(/*top: 10,*/ left: 5),
                      alignment: Alignment.centerLeft,
                      height: 40,
                      child: Text(
                        widget.textOn,
                        style: TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                            fontSize: widget.textSize),
                      ),
                    ),
                  ),
                ),
                Transform.translate(
                  offset: Offset(80 * value, 0),
                  child: Transform.rotate(
                    angle: lerpDouble(0, 2 * pi, value),
                    child: Container(
                      height: 40,
                      width: 40,
                      alignment: Alignment.center,
                      decoration: BoxDecoration(
                          shape: BoxShape.circle, color: Colors.white),
                      child: Stack(
                        children: <Widget>[
                          Center(
                            child: Opacity(
                              opacity: (1 - value).clamp(0.0, 1.0),
                              child: Icon(
                                widget.iconOff,
                                size: 25,
                                color: transitionColor,
                              ),
                            ),
                          ),
                          Center(
                              child: Opacity(
                                  opacity: value.clamp(0.0, 1.0),
                                  child: Icon(
                                    widget.iconOn,
                                    size: 21,
                                    color: transitionColor,
                                  ))),
                        ],
                      ),
                    ),
                  ),
                )
              ],
            ),
          ),
        );
      }
    
      _action() {
        _determine(changeState: true);
      }
    
      _determine({bool changeState = false}) {
        setState(() {
          if (changeState) turnState = !turnState;
          (turnState)
              ? animationController.forward()
              : animationController.reverse();
    
          widget.onChanged(turnState);
        });
      }
    }
    

    【讨论】:

    • 哇...它正在工作,非常感谢您解决这个问题...
    猜你喜欢
    • 2021-02-14
    • 2021-11-23
    • 1970-01-01
    • 2021-08-21
    • 2021-04-08
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 2020-10-05
    相关资源
    最近更新 更多