如何在一个滑块上添加多个滑块? #扑
Posted
技术标签:
【中文标题】如何在一个滑块上添加多个滑块? #扑【英文标题】:how to add multiple sliders on one slider? #Flutter 【发布时间】:2021-12-31 00:09:00 【问题描述】:我想在一个滑块中添加多个滑块。如果你不清楚我在问什么,请参考下图
我希望这三个方块可以滑动并获取它们的值。 我做了一些搜索,找不到任何颤振小部件或支持的插件。
我尝试使用堆栈并在同一位置使用多个 Slider
小部件,但它也无法正常工作。 (我知道这不是一个好方法。)
我怎样才能做到这一点。在同一行上有多个滑块并获取值。 非常感谢任何帮助或想法。
【问题讨论】:
【参考方案1】:将Stack
与三个滑块一起使用不起作用,因为它被重叠了。
我让Slider3X
感到好奇。这里需要修复的东西很少,起点和终点缺少一些小数位置。
Gist、dart pad 上的代码
class Slider3x extends StatefulWidget
const Slider3x(
Key? key,
required this.onSliderUpdate,
this.size = const Size(5, 10),
this.min = 0,
this.max = 1.0,
this.colorX = Colors.green,
this.colorY = Colors.blue,
this.colorZ = Colors.redAccent,
) : super(key: key);
final Function(double? x, double? y, double? z) onSliderUpdate;
///size of moveable 3x point ?, forgot the name maybe thumbs
final Size size;
final double? min;
final double? max;
final Color colorX;
final Color colorY;
final Color colorZ;
@override
State<Slider3x> createState() => _Slider3xState();
class _Slider3xState extends State<Slider3x>
/// three slider position
double? x;
double? y;
double? z;
final double tapSpacesArea = .05;
// currect active slider , help to prevent overlLAp while sliding
int activeSliderNumber = 0;
//* Update sldier
void _updateSlider(double dx, double maxWidth)
final tapPosition = dx;
//* update logic
if (tapPosition <= 0 || tapPosition >= maxWidth)
return;
//* update on UI based on slider number
if (activeSliderNumber == 0)
setState(()
x = tapPosition;
);
else if (activeSliderNumber == 1)
setState(()
y = tapPosition;
);
else if (activeSliderNumber == 2)
setState(()
z = tapPosition;
);
//pass value on main widget
widget.onSliderUpdate(
dp(_generateSliderValue(maxWidth: maxWidth, x: x!)),
dp(_generateSliderValue(maxWidth: maxWidth, x: y!)),
dp(_generateSliderValue(maxWidth: maxWidth, x: z!)),
);
//round number
double dp(double val, int places = 2)
num mod = pow(10.0, places);
return ((val * mod).round().toDouble() / mod);
//* calculate slider value
double _generateSliderValue(
required double maxWidth,
required double x,
)
// x is slider original position on width:maxWidth
return (widget.max! - widget.min!) * (x / maxWidth) + widget.min!;
//* select ActiveSlider, fixed overLap issue
//* slider Selector logic
void _selectSlider(
required double maxWidth,
required double tapPosition,
)
final maxArea = maxWidth * tapSpacesArea;
if ((tapPosition - x!).abs() < maxArea)
setState(()
activeSliderNumber = 0;
);
else if ((tapPosition - y!).abs() < maxArea)
setState(()
activeSliderNumber = 1;
);
else if ((tapPosition - z!).abs() < maxArea)
setState(()
activeSliderNumber = 2;
);
@override
Widget build(BuildContext context)
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 50,
child: LayoutBuilder(builder: (context, constraints)
final maxWidth = constraints.maxWidth - 10;
x = x ?? 0;
y = y ?? constraints.maxWidth / 2;
z = z ?? maxWidth;
return Stack(
alignment: Alignment.center,
children: [
Positioned(
left: x,
child: Container(
height: activeSliderNumber == 0
? widget.size.height * 1.5
: widget.size.height,
width: widget.size.width,
color: widget.colorX,
),
),
//* paint Y
Positioned(
left: y,
child: Container(
height: activeSliderNumber == 1
? widget.size.height * 1.5
: widget.size.height,
width: widget.size.width,
color: widget.colorY,
),
),
//* paint z
Positioned(
left: z,
child: Container(
height: activeSliderNumber == 2
? widget.size.height * 1.5
: widget.size.height,
width: widget.size.width,
color: widget.colorZ,
),
),
const Divider(
endIndent: 10,
),
GestureDetector(
onTapDown: (details) => _selectSlider(
maxWidth: maxWidth,
tapPosition: details.localPosition.dx),
onPanUpdate: (details) =>
_updateSlider(details.localPosition.dx, maxWidth),
),
],
);
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.min.toString(),
),
Text(
widget.max.toString(),
),
],
)
],
),
);
【讨论】:
太棒了!奇迹般有效。非常感谢努力。谢谢以上是关于如何在一个滑块上添加多个滑块? #扑的主要内容,如果未能解决你的问题,请参考以下文章