paint method
- PaintingContext context,
- Offset offset, {
- required RenderBox parentBox,
- required SliderThemeData sliderTheme,
- required Animation<
double> enableAnimation, - required TextDirection textDirection,
- required Offset thumbCenter,
- Offset? secondaryOffset,
- bool isDiscrete = false,
- bool isEnabled = false,
- double additionalActiveTrackHeight = 2,
Paints the track shape based on the state passed to it.
The context
argument is the same as the one that includes the Slider's
render box.
The offset
argument the offset of the origin of the parentBox
to the
origin of its context
canvas. This shape must be painted relative to
this offset. See PaintingContextCallback.
The parentBox
argument is the RenderBox of the Slider. Its attributes,
such as size, can be used to assist in painting this shape.
the sliderTheme
argument is the theme assigned to the Slider that this
shape belongs to.
The enableAnimation
argument is an animation triggered when the Slider
is enabled, and it reverses when the slider is disabled. The Slider is
enabled when Slider.onChanged is not null.Use this to paint intermediate
frames for this shape when the slider changes enabled state.
The thumbCenter
argument is the offset of the center of the thumb
relative to the origin of the PaintingContext.canvas. It can be used as
the point that divides the track into 2 segments.
The secondaryOffset
argument is the offset of the secondary value
relative to the origin of the PaintingContext.canvas.
If not null, the track is divided into 3 segments.
The isEnabled
argument is false when Slider.onChanged is null and true
otherwise. When true, the slider will respond to input.
The isDiscrete
argument is true if Slider.divisions is non-null. When
true, the slider will render tick marks on top of the track.
The textDirection
argument can be used to determine how the track
segments are painted depending on whether they are active or not.
The track segment between the start of the slider and the thumb is the active track segment. The track segment between the thumb and the end of the slider is the inactive track segment. In TextDirection.ltr, the start of the slider is on the left, and in TextDirection.rtl, the start of the slider is on the right.
Implementation
@override
void paint(
PaintingContext context,
Offset offset, {
required RenderBox parentBox,
required SliderThemeData sliderTheme,
required Animation<double> enableAnimation,
required TextDirection textDirection,
required Offset thumbCenter,
Offset? secondaryOffset,
bool isDiscrete = false,
bool isEnabled = false,
double additionalActiveTrackHeight = 2,
}) {
assert(sliderTheme.disabledActiveTrackColor != null);
assert(sliderTheme.disabledInactiveTrackColor != null);
assert(sliderTheme.activeTrackColor != null);
assert(sliderTheme.inactiveTrackColor != null);
assert(sliderTheme.thumbShape != null);
// If the slider [SliderThemeData.trackHeight] is less than or equal to 0,
// then it makes no difference whether the track is painted or not,
// therefore the painting can be a no-op.
if (sliderTheme.trackHeight == null || sliderTheme.trackHeight! <= 0) {
return;
}
// Assign the track segment paints, which are leading: active and
// trailing: inactive.
final ColorTween activeTrackColorTween = ColorTween(begin: sliderTheme.disabledActiveTrackColor, end: sliderTheme.activeTrackColor);
final ColorTween inactiveTrackColorTween = ColorTween(begin: sliderTheme.disabledInactiveTrackColor, end: sliderTheme.inactiveTrackColor);
final Paint activePaint = Paint()..color = activeTrackColorTween.evaluate(enableAnimation)!;
final Paint inactivePaint = Paint()..color = inactiveTrackColorTween.evaluate(enableAnimation)!;
final (Paint leftTrackPaint, Paint rightTrackPaint) = switch (textDirection) {
TextDirection.ltr => (activePaint, inactivePaint),
TextDirection.rtl => (inactivePaint, activePaint),
};
final Rect trackRect = getPreferredRect(
parentBox: parentBox,
offset: offset,
sliderTheme: sliderTheme,
isEnabled: isEnabled,
isDiscrete: isDiscrete,
);
final Radius trackRadius = Radius.circular(trackRect.height / 2);
final Radius activeTrackRadius = Radius.circular((trackRect.height + additionalActiveTrackHeight) / 2);
final bool isLTR = textDirection == TextDirection.ltr;
final bool isRTL = textDirection == TextDirection.rtl;
final bool drawInactiveTrack = thumbCenter.dx < (trackRect.right - (sliderTheme.trackHeight! / 2));
if (drawInactiveTrack) {
// Draw the inactive track segment.
context.canvas.drawRRect(
RRect.fromLTRBR(
thumbCenter.dx - (sliderTheme.trackHeight! / 2),
isRTL ? trackRect.top - (additionalActiveTrackHeight / 2) : trackRect.top,
trackRect.right,
isRTL ? trackRect.bottom + (additionalActiveTrackHeight / 2) : trackRect.bottom,
isLTR ? trackRadius : activeTrackRadius,
),
rightTrackPaint,
);
}
final bool drawActiveTrack = thumbCenter.dx > (trackRect.left + (sliderTheme.trackHeight! / 2));
if (drawActiveTrack) {
// Draw the active track segment.
context.canvas.drawRRect(
RRect.fromLTRBR(
trackRect.left,
isLTR ? trackRect.top - (additionalActiveTrackHeight / 2): trackRect.top,
thumbCenter.dx + (sliderTheme.trackHeight! / 2),
isLTR ? trackRect.bottom + (additionalActiveTrackHeight / 2) : trackRect.bottom,
isLTR ? activeTrackRadius : trackRadius,
),
leftTrackPaint,
);
}
final bool showSecondaryTrack = (secondaryOffset != null) &&
(isLTR ? (secondaryOffset.dx > thumbCenter.dx) : (secondaryOffset.dx < thumbCenter.dx));
if (showSecondaryTrack) {
final ColorTween secondaryTrackColorTween = ColorTween(begin: sliderTheme.disabledSecondaryActiveTrackColor, end: sliderTheme.secondaryActiveTrackColor);
final Paint secondaryTrackPaint = Paint()..color = secondaryTrackColorTween.evaluate(enableAnimation)!;
if (isLTR) {
context.canvas.drawRRect(
RRect.fromLTRBAndCorners(
thumbCenter.dx,
trackRect.top,
secondaryOffset.dx,
trackRect.bottom,
topRight: trackRadius,
bottomRight: trackRadius,
),
secondaryTrackPaint,
);
} else {
context.canvas.drawRRect(
RRect.fromLTRBAndCorners(
secondaryOffset.dx,
trackRect.top,
thumbCenter.dx,
trackRect.bottom,
topLeft: trackRadius,
bottomLeft: trackRadius,
),
secondaryTrackPaint,
);
}
}
}