我对 Flutter 还很陌生,所以目前我无法理解如何自定义滑块轨道以通过分区之间的单独颜色为每个段着色,请帮助实现与下面的屏幕截图相同的设计。
带有颜色的代码片段:
final List<Color> _divisionColors = [
Color(0xff8DF5DE),
Color(0xffA8F58C),
Color(0xffFCEC74),
Color(0xffFCD376),
Color(0xffFDB272),
Color(0xffE27E5A),
];
我知道这个答案已经很晚了。我希望这对其他人有帮助。
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gradient_slider/src/image_thumb_shape.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: ColoredSlider(),
),
),
);
}
}
class ColoredSlider extends StatefulWidget {
@override
_ColoredSliderState createState() => _ColoredSliderState();
}
class _ColoredSliderState extends State<ColoredSlider> {
double _value = 3;
ImageThumbShape? myShape;
@override
void initState() {
super.initState();
_loadImage();
}
@override
Widget build(BuildContext context) {
return Container(
height: 55,
width: 340,
child: SliderTheme(
data: SliderThemeData(
thumbShape: myShape,
overlayShape: const RoundSliderOverlayShape(overlayRadius: 10),
trackHeight: 16, // Adjust the track height
trackShape: CustomTrackShape(), // Set the custom track shape
),
child: Slider(
value: _value,
min: 1,
max: 5,
onChanged: (newValue) {
setState(() {
_value = newValue;
});
},
),
),
);
}
_loadImage() async {
ByteData byData = await rootBundle.load('assets/Triangle.png');
final Uint8List bytes = Uint8List.view(byData.buffer);
final ui.Codec codec = await ui.instantiateImageCodec(bytes, targetWidth: 30, targetHeight: 30);
ui.Image image = (await codec.getNextFrame()).image;
myShape = ImageThumbShape(image: image);
setState(() {});
}
}
class CustomTrackShape extends SliderTrackShape {
@override
Rect getPreferredRect({
required RenderBox parentBox,
Offset? offset = Offset.zero,
required SliderThemeData sliderTheme,
bool? isEnabled,
bool? isDiscrete,
}) {
return Rect.fromLTWH(
offset!.dx,
offset.dy + (parentBox.size.height - sliderTheme.trackHeight!) / 2,
parentBox.size.width,
sliderTheme.trackHeight!,
);
}
@override
void paint(
PaintingContext context,
Offset offset, {
required RenderBox parentBox,
required SliderThemeData sliderTheme,
Animation<double>? enableAnimation,
Offset? thumbCenter,
bool? isEnabled,
bool? isDiscrete,
TextDirection? textDirection,
Offset? secondaryOffset,
}) {
if (sliderTheme.trackHeight == null || sliderTheme.trackHeight! <= 0) {
return;
}
final Rect trackRect = getPreferredRect(
parentBox: parentBox,
offset: offset,
sliderTheme: sliderTheme,
isEnabled: isEnabled,
isDiscrete: isDiscrete,
);
final Paint paint = Paint();
final sliderDivisions = 5; // Your slider division
// Calculate the segment width
final double segmentWidth = trackRect.width / sliderDivisions;
// Paint colored segments between divisions
for (int index = 0; index < sliderDivisions; index++) {
final double startX = trackRect.left + (index * segmentWidth);
final double endX = trackRect.left + ((index + 1) * segmentWidth);
final Rect segmentRect = Rect.fromLTRB(startX, trackRect.top, endX, trackRect.bottom);
// Set different colors for segments
if (index == 0) {
paint.color = Color(0xffF4D11D);
} else if (index == 1) {
paint.color = Color(0xffD1D231);
} else if (index == 2) {
paint.color = Color(0xffB3D342);
} else if (index == 3) {
paint.color = Color(0xff9CD450);
} else if (index == 4) {
paint.color = Color(0xff83D55E);
} else if (index == 5) {
paint.color = Color(0xffF4D11D);
} else if (index == 6) {
paint.color = Colors.green;
}
// Draw rounded rectangle
context.canvas.drawRRect(
RRect.fromRectAndCorners(
segmentRect,
topLeft: index == 0 ? Radius.circular(sliderTheme.trackHeight! / 2) : Radius.zero,
topRight: (index == 5 - 1) ? Radius.circular(sliderTheme.trackHeight! / 2) : Radius.zero,
bottomLeft: index == 0 ? Radius.circular(sliderTheme.trackHeight! / 2) : Radius.zero,
bottomRight: (index == 5 - 1) ? Radius.circular(sliderTheme.trackHeight! / 2) : Radius.zero,
),
paint,
);
// Draw vertical white line
if (index < sliderDivisions - 1) {
final double lineX = startX + segmentWidth;
context.canvas.drawLine(
Offset(lineX, trackRect.top),
Offset(lineX, trackRect.bottom),
Paint()
..color = Colors.white
..strokeWidth = 2.0, // Line Width
);
}
}
}
}