SliderTheme(
data: SliderTheme.of(context).copyWith(
trackHeight: 3,
trackShape: const GradientRectSliderTrackShape(radius: 1.5),
thumbShape: const GradientSliderComponentShape(
rectWH: 14, overlayRectSpace: 4, overlayColor: Colours.black),
),
child: Slider(
value: 3,
inactiveColor: Color(0x55FFFFFF),
min: 1,
max: 10,
),
)
import 'package:flutter/material.dart';
class GradientRectSliderTrackShape extends SliderTrackShape
with BaseSliderTrackShape {
final double disabledThumbGapWidth;
final double radius;
final LinearGradient gradient;
const GradientRectSliderTrackShape(
{this.disabledThumbGapWidth = 2.0,
this.radius = 0,
this.gradient = const LinearGradient(
colors: [Color(0xFFA2FFB7), Color(0xFF00FAED)])});
@override
Rect getPreferredRect({
required RenderBox parentBox,
Offset offset = Offset.zero,
required SliderThemeData sliderTheme,
bool isEnabled = false,
bool isDiscrete = false,
}) {
final double overlayWidth =
sliderTheme.overlayShape!.getPreferredSize(isEnabled, isDiscrete).width;
final double trackHeight = sliderTheme.trackHeight ?? 2;
assert(overlayWidth >= 0);
assert(trackHeight >= 0);
assert(parentBox.size.width >= overlayWidth);
assert(parentBox.size.height >= trackHeight);
final double trackLeft = offset.dx + overlayWidth / 2;
final double trackTop =
offset.dy + (parentBox.size.height - trackHeight) / 2;
final double trackWidth = parentBox.size.width - overlayWidth;
return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight);
}
@override
void paint(
PaintingContext context,
Offset offset, {
required RenderBox parentBox,
required SliderThemeData sliderTheme,
required Animation<double> enableAnimation,
required Offset thumbCenter,
Offset? secondaryOffset,
bool isEnabled = false,
bool isDiscrete = false,
required TextDirection textDirection,
}) {
assert(sliderTheme.disabledActiveTrackColor != null);
assert(sliderTheme.disabledInactiveTrackColor != null);
assert(sliderTheme.activeTrackColor != null);
assert(sliderTheme.inactiveTrackColor != null);
assert(sliderTheme.thumbShape != null);
if (sliderTheme.trackHeight! <= 0) {
return;
}
final Rect trackRect = getPreferredRect(
parentBox: parentBox,
offset: offset,
sliderTheme: sliderTheme,
isEnabled: isEnabled,
isDiscrete: isDiscrete,
);
final ColorTween activeTrackColorTween = ColorTween(
begin: sliderTheme.disabledActiveTrackColor,
end: sliderTheme.activeTrackColor);
final ColorTween inactiveTrackColorTween = ColorTween(
begin: sliderTheme.disabledInactiveTrackColor,
end: sliderTheme.inactiveTrackColor);
final Paint activePaint = Paint()
..shader = gradient.createShader(trackRect)
..color = activeTrackColorTween.evaluate(enableAnimation)!;
final Paint inactivePaint = Paint()
..color = inactiveTrackColorTween.evaluate(enableAnimation)!;
final Paint leftTrackPaint;
final Paint rightTrackPaint;
switch (textDirection) {
case TextDirection.ltr:
leftTrackPaint = activePaint;
rightTrackPaint = inactivePaint;
break;
case TextDirection.rtl:
leftTrackPaint = inactivePaint;
rightTrackPaint = activePaint;
break;
}
double horizontalAdjustment = 0.0;
if (!isEnabled) {
final double disabledThumbRadius =
sliderTheme.thumbShape!.getPreferredSize(false, isDiscrete).width /
2.0;
final double gap = disabledThumbGapWidth * (1.0 - enableAnimation.value);
horizontalAdjustment = disabledThumbRadius + gap;
}
final RRect leftTrackSegment = RRect.fromLTRBR(
trackRect.left,
trackRect.top,
thumbCenter.dx - horizontalAdjustment,
trackRect.bottom,
Radius.circular(radius));
context.canvas.drawRRect(leftTrackSegment, leftTrackPaint);
final RRect rightTrackSegment = RRect.fromLTRBR(
thumbCenter.dx + horizontalAdjustment,
trackRect.top,
trackRect.right,
trackRect.bottom,
Radius.circular(radius));
context.canvas.drawRRect(rightTrackSegment, rightTrackPaint);
}
}
import 'package:flutter/material.dart';
class GradientSliderComponentShape extends SliderComponentShape {
final double rectWH;
final double overlayRectSpace;
final LinearGradient thumbGradient;
final Color? overlayColor;
const GradientSliderComponentShape(
{required this.rectWH,
required this.overlayRectSpace,
this.thumbGradient =
const LinearGradient(colors: [Color(0xFFA2FFB7), Color(0xFF00FAED)]),
this.overlayColor});
@override
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return const Size(0, 0);
}
@override
void paint(PaintingContext context, Offset center,
{required Animation<double> activationAnimation,
required Animation<double> enableAnimation,
required bool isDiscrete,
required TextPainter labelPainter,
required RenderBox parentBox,
required SliderThemeData sliderTheme,
required TextDirection textDirection,
required double value,
required double textScaleFactor,
required Size sizeWithOverflow}) {
final Canvas canvas = context.canvas;
double overlayWH = rectWH + overlayRectSpace;
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromCenter(center: center, width: overlayWH, height: overlayWH),
Radius.circular(overlayWH / 2),
),
Paint()
..color = (overlayColor != null)
? overlayColor!
: const Color.fromARGB(255, 252, 241, 216),
);
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromCenter(center: center, width: rectWH, height: rectWH),
Radius.circular(rectWH / 2),
),
Paint()
..shader = thumbGradient.createShader(
Rect.fromCenter(center: center, width: rectWH, height: rectWH)));
}
}