我尝试在Flutter中构建自己的滑块。
但我遇到了问题。
如何创建类似flutter默认滑块onChanged的回调? 为了拥有我们自己的滑块,我们需要注册一个CallBack,但我不知道该怎么做?
这是我到目前为止的努力。
import 'dart:math';
import 'package:flutter/material.dart';
class WaveSlider extends StatefulWidget {
final double value;
final double barWidth;
final int maxBarHight;
final double width;
final double min;
final double max;
final Color barColor;
final Color barSideColor;
final Color inActiveColor;
WaveSlider({
this.value = 0.0,
this.barWidth = 5.0,
this.maxBarHight = 50,
this.width = 60.0,
this.min = 0.0,
this.max = 1.0,
this.barColor = Colors.white,
this.barSideColor = Colors.black,
this.inActiveColor = Colors.grey,
});
@override
State<StatefulWidget> createState() => WaveSliderState();
}
class WaveSliderState extends State<WaveSlider>
with SingleTickerProviderStateMixin {
AnimationController positionController;
List<int> bars = [];
double barPosition;
double barWidth;
int maxBarHight;
double width;
int numberOfBars;
@override
void initState() {
super.initState();
barPosition = widget.value;
barWidth = widget.barWidth;
maxBarHight = widget.maxBarHight.toInt();
width = widget.width;
if (bars.isNotEmpty) bars = [];
numberOfBars = width ~/ barWidth;
randomNumberGenerator();
}
void randomNumberGenerator() {
Random r = Random();
for (var i = 0; i < numberOfBars; i++) {
bars.add(r.nextInt(maxBarHight - 10) + 10);
}
}
_onTapDown(TapDownDetails details) {
var x = details.globalPosition.dx;
print("tapped " + (x).toString());
// print(positionController.value);
setState(() {
barPosition = x;
});
}
void _onHorizontalDragUpdate(DragUpdateDetails details) {
setState(() {
barPosition = details.globalPosition.dx;
});
}
@override
Widget build(BuildContext context) {
int barItem = 0;
return Center(
child: GestureDetector(
onTapDown: _onTapDown,
onHorizontalDragUpdate: _onHorizontalDragUpdate,
child: Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.center,
children: bars.map((int height) {
Color color = barItem + 1 < barPosition / barWidth
? widget.barColor
: widget.inActiveColor;
barItem++;
return Row(
children: <Widget>[
Container(
width: .1,
height: height.toDouble(),
color: widget.barSideColor,
),
Container(
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(1.0),
topRight: const Radius.circular(1.0),
),
),
height: height.toDouble(),
width: 4.8,
),
Container(
width: .1,
height: height.toDouble(),
color: widget.barSideColor,
),
],
);
}).toList(),
),
),
),
);
}
}
您可以像这样使用它:
WaveSlider(
value: _animation.value,
min: 0.0,
max: 1.0,
width: MediaQuery.of(context).size.width,
barWidth: 5,
maxBarHight: 50,
barColor: Colors.black,
barSideColor: Colors.white,
inActiveColor: Colors.red,
)
我查看了默认的颤动滑块,但对我来说非常执着。 非常感谢。
答案 0 :(得分:1)
我添加了如下回调:
import 'dart:math';
import 'package:flutter/material.dart';
class WaveSlider extends StatefulWidget {
final double value;
final double barWidth;
final int maxBarHight;
final double width;
final double min;
final double max;
final Color barColor;
final Color barSideColor;
final Color inActiveColor;
final CalbackFunction callback;
WaveSlider({
this.value = 0.0,
this.barWidth = 5.0,
this.maxBarHight = 50,
this.width = 60.0,
this.min = 0.0,
this.max = 1.0,
this.barColor = Colors.white,
this.barSideColor = Colors.black,
this.inActiveColor = Colors.grey,
this.callback,
});
@override
State<StatefulWidget> createState() => WaveSliderState();
}
class WaveSliderState extends State<WaveSlider>
with SingleTickerProviderStateMixin {
AnimationController positionController;
List<int> bars = [];
double barPosition;
double barWidth;
int maxBarHight;
double width;
int numberOfBars;
@override
void initState() {
super.initState();
barPosition = widget.value;
barWidth = widget.barWidth;
maxBarHight = widget.maxBarHight.toInt();
width = widget.width;
if (bars.isNotEmpty) bars = [];
numberOfBars = width ~/ barWidth;
randomNumberGenerator();
}
void randomNumberGenerator() {
Random r = Random();
for (var i = 0; i < numberOfBars; i++) {
bars.add(r.nextInt(maxBarHight - 10) + 10);
}
}
_onTapDown(TapDownDetails details) {
var x = details.globalPosition.dx;
// print("tapped " + (x).toString());
widget.callback(details.globalPosition); /// <-- I used callback here
// print(positionController.value);
setState(() {
barPosition = x;
});
}
void _onHorizontalDragUpdate(DragUpdateDetails details) {
widget.callback(details.globalPosition); /// <-- I used callback here
setState(() {
barPosition = details.globalPosition.dx;
});
}
@override
Widget build(BuildContext context) {
int barItem = 0;
return Center(
child: GestureDetector(
onTapDown: _onTapDown,
onHorizontalDragUpdate: _onHorizontalDragUpdate,
child: Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.center,
children: bars.map((int height) {
Color color = barItem + 1 < barPosition / barWidth
? widget.barColor
: widget.inActiveColor;
barItem++;
return Row(
children: <Widget>[
Container(
width: .1,
height: height.toDouble(),
color: widget.barSideColor,
),
Container(
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(1.0),
topRight: const Radius.circular(1.0),
),
),
height: height.toDouble(),
width: 4.8,
),
Container(
width: .1,
height: height.toDouble(),
color: widget.barSideColor,
),
],
);
}).toList(),
),
),
),
);
}
}
typedef CalbackFunction = void Function(Offset value);
您可以按以下方式使用它:
WaveSlider(
value: 0.0,
min: 0.0,
max: 1.0,
width: MediaQuery.of(context).size.width,
barWidth: 5,
maxBarHight: 50,
barColor: Colors.black,
barSideColor: Colors.white,
inActiveColor: Colors.red,
callback: (offset) {
print("callback " + (offset.dx).toString());
},
))
希望它能对您有所帮助。
答案 1 :(得分:0)
wave_slider package的文档显示它具有用于回调的onChanged属性:
WaveSlider(
onChanged: (double dragUpdate) {
setState(() {
_dragPercentage = dragUpdate *
100; // dragUpdate is a fractional value between 0 and 1
});
},
)