flutter - 在Flutter构建期间调用setState

标签 flutter dart

我正在尝试制作一个Flutter应用程序,我要做的就是在用户更改LiteRollingSwitch时将bool isSwitched切换为true或false。 (我使用了这个https://pub.dev/packages/lite_rolling_switch#-readme-tab-库)。在onchage方法内部,如果我创建“setstate”,则会给我类似下面的错误。
enter image description here
但是我需要根据用户的选择将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;
                                      });
                                    },
                                  ),
                                ),

最佳答案

好消息:这不是你的错。
坏消息:您必须修改他们的代码,或者等到他们更改它。
我在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);
    });
  }
}

关于flutter - 在Flutter构建期间调用setState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62498135/

相关文章:

dart - 动态更改 AlertDialog 标题 (showDialog())

dart - Flutter PaginatedDataTable rowsPerPage

dart - 强制堆栈重新创建自定义小部件

entity-framework - 在 Flutter 中使用 Bloc 架构时调用 setState 方法是一个好习惯吗?

dart - Flutter 在 `flutter` 命令上失败

flutter - 如何在 Dart 中取消延迟的 future ?

flutter - ClipPath

ios - Flutter 'Error running pod install' 'Pods-Runner' 目标具有传递依赖

data-binding - Dart + Polymer,如何绑定(bind)到以编程方式生成的元素、textarea、select、optgroup

flutter - 小部件文本中的文本OverFlow.ellipsis不起作用