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 = 0,
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 = 0}) {
super.paint(context, offset,
parentBox: parentBox,
sliderTheme: sliderTheme,
enableAnimation: enableAnimation,
textDirection: textDirection,
thumbCenter: thumbCenter,
additionalActiveTrackHeight: additionalActiveTrackHeight);
// 绘制 缓冲进度条颜色
if (secondaryOffset == null ||
sliderTheme.secondaryActiveTrackColor == null) {
return;
}
// 获取轨道的基本矩形信息
final Rect trackRect = getPreferredRect(
parentBox: parentBox,
offset: offset,
sliderTheme: sliderTheme,
isEnabled: isEnabled,
isDiscrete: isDiscrete,
);
// 确定绘制区域的左右边界
// 注意:secondaryOffset 可能在 thumbCenter 的左边或右边,取决于 textDirection 和值的大小
double startX;
double endX;
if (textDirection == TextDirection.ltr) {
// LTR: thumbCenter 是起点,secondaryOffset 是终点
startX = thumbCenter.dx;
endX = secondaryOffset.dx;
} else {
// RTL: secondaryOffset 是起点,thumbCenter 是终点
startX = secondaryOffset.dx;
endX = thumbCenter.dx;
}
// 如果 secondaryTrackValue <= value,则 startX >= endX,无需绘制
if (startX >= endX) {
return;
}
// 构建绘制矩形
final Rect secondaryRect = Rect.fromLTRB(
startX,
trackRect.top,
endX,
trackRect.bottom,
);
// 创建画笔
final Paint secondaryPaint = Paint()
..color = sliderTheme.secondaryActiveTrackColor!
..style = PaintingStyle.fill;
// 为了保持美观,使用与主轨道相同的圆角半径
final double trackHeight = sliderTheme.trackHeight ?? 2.0;
final Radius radius = Radius.circular(trackHeight / 2);
// 使用 RRect 绘制,确保两端也是圆角(或者至少右端是圆角)
// 注意:如果希望与主轨道无缝衔接,左端(靠近 thumb)可以是直角,但通常全圆角更美观
final RRect secondaryRRect = RRect.fromRectAndRadius(
secondaryRect,
radius,
);
context.canvas.drawRRect(secondaryRRect, secondaryPaint);
}