I am trying to create a Range Slider with a gradient body.
I have based my code on a Gradient Slider code from this response: Flutter slider with gradient
I adjusted the Paint override depending on the Interface of the object.
So this is the situation:
Error
======== Exception caught by rendering library =====================================================
The following _CastError was thrown during paint():
Null check operator used on a null value
The relevant error-causing widget was:
RangeSlider RangeSlider:file:///[PATH]flutter/lib/source/shared_components/common/slider_range/slider_range.item.dart:19:14
When the exception was thrown, this was the stack:
#0 BaseSliderTrackShape.getPreferredRect (package:flutter/src/material/slider_theme.dart:1484:53)
#1 _RenderRangeSlider.paint (package:flutter/src/material/range_slider.dart:1267:58)
#2 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#3 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#4 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:140:15)
#5 PaintingContext.pushLayer (package:flutter/src/rendering/object.dart:387:12)
#6 RenderLeaderLayer.paint (package:flutter/src/rendering/proxy_box.dart:5138:13)
#7 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#8 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#9 RenderBoxContainerDefaultsMixin.defaultPaint (package:flutter/src/rendering/box.dart:2844:15)
#10 RenderFlex.paint (package:flutter/src/rendering/flex.dart:1078:7)
#11 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#12 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#13 RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:79:15)
#14 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#15 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#16 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:140:15)
#17 RenderDecoratedBox.paint (package:flutter/src/rendering/proxy_box.dart:2169:11)
#18 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#19 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#20 RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:79:15)
#21 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#22 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#23 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:140:15)
#24 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#25 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#26 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:140:15)
#27 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#28 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#29 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:140:15)
#30 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#31 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#32 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:140:15)
#33 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#34 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#35 RenderBoxContainerDefaultsMixin.defaultPaint (package:flutter/src/rendering/box.dart:2844:15)
#36 RenderFlex.paint (package:flutter/src/rendering/flex.dart:1078:7)
#37 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#38 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#39 RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:79:15)
#40 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#41 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:187:13)
#42 _RenderSingleChildViewport.paint.paintContents (package:flutter/src/widgets/single_child_scroll_view.dart:542:17)
#43 _RenderSingleChildViewport.paint (package:flutter/src/widgets/single_child_scroll_view.dart:556:9)
#44 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2451:7)
#45 PaintingContext._repaintCompositedChild (package:flutter/src/rendering/object.dart:141:11)
#46 PaintingContext.repaintCompositedChild (package:flutter/src/rendering/object.dart:100:5)
#47 PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:995:29)
#48 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:499:19)
#49 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:883:13)
#50 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:363:5)
#51 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1144:15)
#52 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1081:9)
#53 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:995:5)
#57 _invoke (dart:ui/hooks.dart:151:10)
#58 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:308:5)
#59 _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
The following RenderObject was being processed when the exception was fired: _RenderRangeSlider#59316
... parentData: <none> (can use size)
... constraints: BoxConstraints(0.0<=w<=367.4, 0.0<=h<=Infinity)
... semantic boundary
... size: Size(367.4, 48.0)
RenderObject: _RenderRangeSlider#59316
parentData: <none> (can use size)
constraints: BoxConstraints(0.0<=w<=367.4, 0.0<=h<=Infinity)
semantic boundary
size: Size(367.4, 48.0)
====================================================================================================
Track
import 'package:flutter/material.dart';
class GradientRectRangeSliderTrackShape extends RangeSliderTrackShape
with BaseSliderTrackShape {
const GradientRectRangeSliderTrackShape({
this.gradient = const LinearGradient(
colors: [
Colors.red,
Colors.yellow,
],
),
this.darkenInactive = true,
});
final LinearGradient gradient;
final bool darkenInactive;
@override
void paint(
PaintingContext context,
Offset offset,
{
required RenderBox parentBox,
required SliderThemeData sliderTheme,
required Animation<double> enableAnimation,
required TextDirection textDirection,
required Offset startThumbCenter,
required Offset endThumbCenter,
bool isDiscrete = false,
bool isEnabled = false,
double additionalActiveTrackHeight = 2,
}
) {
assert(
sliderTheme.disabledActiveTrackColor != null,
'sliderTheme.disabledActiveTrackColor is required'
);
assert(
sliderTheme.disabledInactiveTrackColor != null,
'sliderTheme.disabledInactiveTrackColor is required'
);
assert(
sliderTheme.activeTrackColor != null,
'sliderTheme.activeTrackColor is required'
);
assert(
sliderTheme.inactiveTrackColor != null,
'sliderTheme.inactiveTrackColor'
);
assert(
sliderTheme.thumbShape != null,
'sliderTheme.thumbShape is required'
);
assert(
sliderTheme.trackHeight != null && sliderTheme.trackHeight! > 0,
'sliderTheme.trackHeight != null and sliderTheme.trackHeight! > 0'
'are required'
);
final Rect trackRect = getPreferredRect(
parentBox: parentBox,
offset: offset,
sliderTheme: sliderTheme,
isEnabled: isEnabled,
isDiscrete: isDiscrete,
);
final activeGradientRect = Rect.fromLTRB(
startThumbCenter.dx,
(textDirection == TextDirection.ltr)
? trackRect.top - (additionalActiveTrackHeight / 2)
: trackRect.top,
endThumbCenter.dx,
(textDirection == TextDirection.ltr)
? trackRect.bottom + (additionalActiveTrackHeight / 2)
: trackRect.bottom,
);
// 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 = darkenInactive
? ColorTween(
begin: sliderTheme.disabledInactiveTrackColor,
end: sliderTheme.inactiveTrackColor
)
: activeTrackColorTween;
final Paint activePaint = Paint()
..shader = gradient.createShader(activeGradientRect)
..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;
}
final Radius trackRadius = Radius.circular(trackRect.height / 2);
final Radius activeTrackRadius = Radius.circular(trackRect.height / 2 + 1);
context.canvas.drawRRect(
RRect.fromLTRBAndCorners(
startThumbCenter.dx,
(textDirection == TextDirection.ltr)
? trackRect.top - (additionalActiveTrackHeight / 2)
: trackRect.top,
endThumbCenter.dx,
(textDirection == TextDirection.ltr)
? trackRect.bottom + (additionalActiveTrackHeight / 2)
: trackRect.bottom,
topLeft: (textDirection == TextDirection.ltr)
? activeTrackRadius
: trackRadius,
bottomLeft: (textDirection == TextDirection.ltr)
? activeTrackRadius
: trackRadius,
),
leftTrackPaint,
);
context.canvas.drawRRect(
RRect.fromLTRBAndCorners(
startThumbCenter.dx,
(textDirection == TextDirection.rtl)
? trackRect.top - (additionalActiveTrackHeight / 2)
: trackRect.top,
endThumbCenter.dx,
(textDirection == TextDirection.rtl)
? trackRect.bottom + (additionalActiveTrackHeight / 2)
: trackRect.bottom,
topRight: (textDirection == TextDirection.rtl)
? activeTrackRadius
: trackRadius,
bottomRight: (textDirection == TextDirection.rtl)
? activeTrackRadius
: trackRadius,
),
rightTrackPaint,
);
}
}
Widget
SliderTheme(
data: SliderThemeData(
rangeTrackShape: GradientRectRangeSliderTrackShape()
),
child: RangeSlider(
onChanged: onChanged,
values: data.values,
min: data.min,
max: data.max,
divisions: data.labels.length
)
)