首页 > 解决方案 > 颤振,slider_button

问题描述

我是 Flutter 的新手,我正在尝试创建一个可拖动的按钮来接受或拒绝请求,我使用了 Dtaggable 小部件,但它给了我很多问题,最后一个是将 Dragable(button) 限制为容器,因此我看到 Dragabble 不是为此而设计的,我应该使用 GestureDetector 代替,但是当我尝试时,我无法将按钮定位在中心并让我很好地保持距离,如果有人能给我一个手,我会很感激的。


class SliderButton extends StatefulWidget {
  final double containerWidth;
  final double containerHeight;
  final Color containerColor;

  final double buttonSize;
  final Color buttonColor;

  final Color textColor;
  final double textSize;

  final String leftText;
  final String rightText;

  final String textResultDeny;
  final String textResultAccept;

  final IconData icon;
  final Color iconColor;

  final Function(BuildContext context)? sliderPrimaryFunction;
  final Function(BuildContext context)? sliderSecondaryFunction;

  SliderButton(
      {required this.containerWidth,
      required this.containerHeight,
      this.containerColor = Colors.black,
      this.buttonSize = 50,
      this.buttonColor = Colors.white,
      this.rightText = 'Aceptar',
      this.textResultAccept = 'Aceptado',
      this.leftText = 'Denegar',
      this.textResultDeny = 'Denegado',
      this.sliderPrimaryFunction,
      this.sliderSecondaryFunction,
      this.textColor = Colors.white,
      this.textSize = 24,
      this.icon = Icons.add_circle_outline,
      this.iconColor = Colors.black});

  @override
  _SliderButtonState createState() => _SliderButtonState();
}

class _SliderButtonState extends State<SliderButton> {
  Offset position = Offset(0, 0);
  bool started = false;
  int switchOptions = 0;
  Color? _containerColor = Colors.black;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: sliderContainer(),
    );
  }

  sliderContainer() => Container(
      width: this.widget.containerWidth,
      height: this.widget.containerHeight,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(50.00),
        color: _containerColor,
        boxShadow: [
          BoxShadow(
            color: Colors.black,
            offset: Offset(0.0, 1.0),
            blurRadius: 6.0,
          ),
        ],
      ),
      child: sliderContainerContent());

  sliderContainerContent() {
    if (switchOptions == 0) return Center(child: containerContent());
    if (switchOptions == 1)
      return textResult(this.widget.textResultAccept);
    else if (switchOptions == 2) return textResult(this.widget.textResultDeny);
  }

  containerContent() => Container(
    width: this.widget.containerWidth,
    height: this.widget.containerHeight,
    child: Row(
          children: [
            started == false
                ? primaryText(this.widget.leftText, Alignment.centerLeft)
                : Container(),
            Center(
                child: Container(
                  child: Draggable(
                    axis: Axis.horizontal,
                    feedback: roundedButton(),
                    child: started == false ? roundedButton() : Container(),
                    onDragStarted: () => setState(() {
                      started = true;
                    }),
                    onDragUpdate: (details) => _sequentialColor(details),
                    onDragEnd: (details) => _onSlideDragUpdate(details),
                  ),
                ),
            ),
            started == false
                ? primaryText(this.widget.rightText, Alignment.centerRight)
                : Container(),
          ],
        ),
  );

  roundedButton() => Align(
        child: Container(
          width: this.widget.buttonSize,
          height: this.widget.buttonSize,
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            color: this.widget.buttonColor,
            boxShadow: [
              BoxShadow(
                color: Colors.grey,
                offset: Offset(0.0, 1.0),
                blurRadius: 6.0,
              ),
            ],
          ),
          child: Icon(this.widget.icon,
              color: this.widget.iconColor, size: this.widget.buttonSize),
        ),
      );

  primaryText(String text, Alignment alignment) => Container(
        alignment: alignment,
        padding: EdgeInsets.all(14.0),
        child: Text(text,
            style: Theme.of(context)
                .textTheme
                .headline5
                ?.copyWith(color: Colors.white)),
      );

  textResult(String text) => Center(
      child: Text(text,
          style: Theme.of(context)
              .textTheme
              .headline3
              ?.copyWith(color: Colors.white)));

  void _sequentialColor(DragUpdateDetails details) {
    print(details.localPosition.dx);
    var initColor = 200;
    var algo = 240;
    var algo2 = 200;
    for (var i = details.localPosition.dx; i > algo; i++) {
      setState(() {
        _containerColor = Colors.green[initColor];
        initColor += 100;
        algo += 30;
      });
    }
    for (var i = details.localPosition.dx; i < algo2; i--) {
      setState(() {
        _containerColor = Colors.red[initColor];
        initColor += 100;
        algo2 -= 30;
      });
    }
  }

  void _onSlideDragUpdate(DraggableDetails details) {
    if (details.offset.distance > 470) {
      setState(() {
        switchOptions = 1;
        _containerColor = Colors.lightGreen;
        Future.delayed(const Duration(milliseconds: 500), () {
          this.widget.sliderPrimaryFunction ?? Navigator.pop(context);
        });
      });
    } else if (details.offset.distance < 400) {
      setState(() {
        switchOptions = 2;
        _containerColor = Theme.of(context).errorColor;
        Future.delayed(const Duration(milliseconds: 500), () {
          this.widget.sliderPrimaryFunction ?? Navigator.pop(context);
        });
      });
    } else
      setState(() {
        _containerColor = Theme.of(context).primaryColorDark;
        started = false;
      });
  }
}

标签: flutter

解决方案


您可以在此包中执行此操作。 https://pub.dev/packages/slider_button 这是一个插件示例。如果您对包裹有疑问。我很乐意帮助您配置自己的代码

Center(child: SliderButton(
      action: () {
        ///Do something here
        Navigator.of(context).pop();
      },
       label: Text(
          "Slide to cancel Event",
          style: TextStyle(
              color: Color(0xff4a4a4a), fontWeight: FontWeight.w500, fontSize: 17),
        ),
      icon: Text(
        "x",
        style: TextStyle(
          color: Colors.white,
          fontWeight: FontWeight.w400,
          fontSize: 44,
        ),
      ),


    ));

推荐阅读