flutter - 颤振,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;
});
}
}
解决方案
您可以在此包中执行此操作。 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,
),
),
));
推荐阅读
- amazon-web-services - 具有 ec2 源的 Cloudfront
- c++ - 如何将文本文件添加到游戏中,以便它可以跟踪一个人的分数
- c - C语言的问题,我不明白错误
- ruby - 推送 Ruby gem 时出错(凭证“未找到”)
- xcode - 应用程序在设备和 Mac Sim 上构建和运行,无需手机模拟 [M1]
- javascript - 当用户停止输入搜索框时执行 api 请求
- c# - C#编码输入输出问题
- javascript - 如何将此动态 index.html 页面转换为 React 页面并将其连接到同一个 Nodejs express 页面?
- php - 检查客户是否购买了东西并将产品添加到 WooCommerce 中的购物车
- python - Pandas 多页 concat 和多维石斑鱼