paint method

  1. @override
void paint(
  1. PaintingContext context,
  2. Offset offset, {
  3. required RenderBox parentBox,
  4. required SliderThemeData sliderTheme,
  5. required Animation<double> enableAnimation,
  6. required Offset startThumbCenter,
  7. required Offset endThumbCenter,
  8. bool isEnabled = false,
  9. bool isDiscrete = false,
  10. required TextDirection textDirection,
  11. double additionalActiveTrackHeight = 2,
})
override

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 is 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 RangeSlider. Its attributes, such as size, can be used to assist in painting this shape.

The sliderTheme argument is the theme assigned to the RangeSlider that this shape belongs to.

The enableAnimation argument is an animation triggered when the RangeSlider is enabled, and it reverses when the slider is disabled. The RangeSlider is enabled when RangeSlider.onChanged is not null. Use this to paint intermediate frames for this shape when the slider changes enabled state.

The startThumbCenter argument is the offset of the center of the start thumb relative to the origin of the PaintingContext.canvas. It can be used as one point that divides the track between inactive and active.

The endThumbCenter argument is the offset of the center of the end thumb relative to the origin of the PaintingContext.canvas. It can be used as one point that divides the track between inactive and active.

The isEnabled argument is false when RangeSlider.onChanged is null and true otherwise. When true, the slider will respond to input.

The isDiscrete argument is true if RangeSlider.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 on an active track segment or not.

The track segment between the two thumbs is the active track segment. The track segments between the thumb and each end of the slider are the inactive track segments. 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 Offset startThumbCenter,
  required Offset endThumbCenter,
  bool isEnabled = false,
  bool isDiscrete = false,
  required TextDirection textDirection,
  double additionalActiveTrackHeight = 2,
}) {
  assert(sliderTheme.disabledActiveTrackColor != null);
  assert(sliderTheme.disabledInactiveTrackColor != null);
  assert(sliderTheme.activeTrackColor != null);
  assert(sliderTheme.inactiveTrackColor != null);
  assert(sliderTheme.rangeThumbShape != null);

  if (sliderTheme.trackHeight == null || sliderTheme.trackHeight! <= 0) {
    return;
  }

  // Assign the track segment paints, which are left: active, right: inactive,
  // but reversed for right to left text.
  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 (Offset leftThumbOffset, Offset rightThumbOffset) = switch (textDirection) {
    TextDirection.ltr => (startThumbCenter, endThumbCenter),
    TextDirection.rtl => (endThumbCenter, startThumbCenter),
  };
  final Size thumbSize = sliderTheme.rangeThumbShape!.getPreferredSize(isEnabled, isDiscrete);
  final double thumbRadius = thumbSize.width / 2;
  assert(thumbRadius > 0);

  final Rect trackRect = getPreferredRect(
    parentBox: parentBox,
    offset: offset,
    sliderTheme: sliderTheme,
    isEnabled: isEnabled,
    isDiscrete: isDiscrete,
  );

  final Radius trackRadius = Radius.circular(trackRect.height / 2);

  context.canvas.drawRRect(
    RRect.fromLTRBAndCorners(
      trackRect.left,
      trackRect.top,
      leftThumbOffset.dx,
      trackRect.bottom,
      topLeft: trackRadius,
      bottomLeft: trackRadius,
    ),
    inactivePaint,
  );
  context.canvas.drawRect(
    Rect.fromLTRB(
      leftThumbOffset.dx,
      trackRect.top - (additionalActiveTrackHeight / 2),
      rightThumbOffset.dx,
      trackRect.bottom + (additionalActiveTrackHeight / 2),
    ),
    activePaint,
  );
  context.canvas.drawRRect(
    RRect.fromLTRBAndCorners(
      rightThumbOffset.dx,
      trackRect.top,
      trackRect.right,
      trackRect.bottom,
      topRight: trackRadius,
      bottomRight: trackRadius,
    ),
    inactivePaint,
  );
}