Add slider customizations (#11185)
* adds inactiveColor and showThumb to Slider * add customizable color and showThumb tests * remove showThumb, add negative tests
This commit is contained in:
parent
56700930a5
commit
bb15e346bb
@ -64,6 +64,7 @@ class Slider extends StatefulWidget {
|
||||
this.divisions,
|
||||
this.label,
|
||||
this.activeColor,
|
||||
this.inactiveColor,
|
||||
this.thumbOpenAtMin: false,
|
||||
}) : assert(value != null),
|
||||
assert(min != null),
|
||||
@ -138,6 +139,11 @@ class Slider extends StatefulWidget {
|
||||
/// Defaults to accent color of the current [Theme].
|
||||
final Color activeColor;
|
||||
|
||||
/// The color for the unselected portion of the slider.
|
||||
///
|
||||
/// Defaults to the unselected widget color of the current [Theme].
|
||||
final Color inactiveColor;
|
||||
|
||||
/// Whether the thumb should be an open circle when the slider is at its minimum position.
|
||||
///
|
||||
/// When this property is false, the thumb does not change when it the slider
|
||||
@ -178,6 +184,7 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin {
|
||||
divisions: widget.divisions,
|
||||
label: widget.label,
|
||||
activeColor: widget.activeColor ?? theme.accentColor,
|
||||
inactiveColor: widget.inactiveColor ?? theme.unselectedWidgetColor,
|
||||
thumbOpenAtMin: widget.thumbOpenAtMin,
|
||||
textTheme: theme.accentTextTheme,
|
||||
onChanged: (widget.onChanged != null) && (widget.max > widget.min) ? _handleChanged : null,
|
||||
@ -193,6 +200,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
|
||||
this.divisions,
|
||||
this.label,
|
||||
this.activeColor,
|
||||
this.inactiveColor,
|
||||
this.thumbOpenAtMin,
|
||||
this.textTheme,
|
||||
this.onChanged,
|
||||
@ -203,6 +211,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
|
||||
final int divisions;
|
||||
final String label;
|
||||
final Color activeColor;
|
||||
final Color inactiveColor;
|
||||
final bool thumbOpenAtMin;
|
||||
final TextTheme textTheme;
|
||||
final ValueChanged<double> onChanged;
|
||||
@ -215,6 +224,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
|
||||
divisions: divisions,
|
||||
label: label,
|
||||
activeColor: activeColor,
|
||||
inactiveColor: inactiveColor,
|
||||
thumbOpenAtMin: thumbOpenAtMin,
|
||||
textTheme: textTheme,
|
||||
onChanged: onChanged,
|
||||
@ -229,6 +239,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
|
||||
..divisions = divisions
|
||||
..label = label
|
||||
..activeColor = activeColor
|
||||
..inactiveColor = inactiveColor
|
||||
..thumbOpenAtMin = thumbOpenAtMin
|
||||
..textTheme = textTheme
|
||||
..onChanged = onChanged;
|
||||
@ -246,11 +257,9 @@ const double _kMinimumTrackWidth = _kActiveThumbRadius; // biggest of the thumb
|
||||
const double _kPreferredTotalWidth = _kPreferredTrackWidth + 2 * _kReactionRadius;
|
||||
const double _kMinimumTotalWidth = _kMinimumTrackWidth + 2 * _kReactionRadius;
|
||||
|
||||
final Color _kInactiveTrackColor = Colors.grey.shade400;
|
||||
final Color _kActiveTrackColor = Colors.grey;
|
||||
final Tween<double> _kReactionRadiusTween = new Tween<double>(begin: _kThumbRadius, end: _kReactionRadius);
|
||||
final Tween<double> _kThumbRadiusTween = new Tween<double>(begin: _kThumbRadius, end: _kActiveThumbRadius);
|
||||
final ColorTween _kTrackColorTween = new ColorTween(begin: _kInactiveTrackColor, end: _kActiveTrackColor);
|
||||
final ColorTween _kTickColorTween = new ColorTween(begin: Colors.transparent, end: Colors.black54);
|
||||
final Duration _kDiscreteTransitionDuration = const Duration(milliseconds: 500);
|
||||
|
||||
@ -276,6 +285,7 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
||||
int divisions,
|
||||
String label,
|
||||
Color activeColor,
|
||||
Color inactiveColor,
|
||||
bool thumbOpenAtMin,
|
||||
TextTheme textTheme,
|
||||
this.onChanged,
|
||||
@ -284,6 +294,7 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
||||
_value = value,
|
||||
_divisions = divisions,
|
||||
_activeColor = activeColor,
|
||||
_inactiveColor = inactiveColor,
|
||||
_thumbOpenAtMin = thumbOpenAtMin,
|
||||
_textTheme = textTheme {
|
||||
this.label = label;
|
||||
@ -363,6 +374,15 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
Color get inactiveColor => _inactiveColor;
|
||||
Color _inactiveColor;
|
||||
set inactiveColor(Color value) {
|
||||
if (value == _inactiveColor)
|
||||
return;
|
||||
_inactiveColor = value;
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
bool get thumbOpenAtMin => _thumbOpenAtMin;
|
||||
bool _thumbOpenAtMin;
|
||||
set thumbOpenAtMin(bool value) {
|
||||
@ -451,7 +471,6 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
double computeMinIntrinsicWidth(double height) {
|
||||
return _kMinimumTotalWidth;
|
||||
@ -501,8 +520,8 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
||||
final double trackRight = trackLeft + trackLength;
|
||||
final double trackActive = trackLeft + trackLength * value;
|
||||
|
||||
final Paint primaryPaint = new Paint()..color = enabled ? _activeColor : _kInactiveTrackColor;
|
||||
final Paint trackPaint = new Paint()..color = _kTrackColorTween.evaluate(_reaction);
|
||||
final Paint primaryPaint = new Paint()..color = enabled ? _activeColor : _inactiveColor;
|
||||
final Paint trackPaint = new Paint()..color = _inactiveColor;
|
||||
|
||||
final Offset thumbCenter = new Offset(trackActive, trackCenter);
|
||||
final double thumbRadius = enabled ? _kThumbRadiusTween.evaluate(_reaction) : _kDisabledThumbRadius;
|
||||
|
@ -118,6 +118,72 @@ void main() {
|
||||
log.clear();
|
||||
});
|
||||
|
||||
testWidgets('Slider has a customizable active color',
|
||||
(WidgetTester tester) async {
|
||||
final Color customColor = const Color(0xFF4CD964);
|
||||
final ThemeData theme = new ThemeData(platform: TargetPlatform.android);
|
||||
Widget buildApp(Color activeColor) {
|
||||
return new Material(
|
||||
child: new Center(
|
||||
child: new Theme(
|
||||
data: theme,
|
||||
child: new Slider(
|
||||
value: 0.5,
|
||||
activeColor: activeColor,
|
||||
onChanged: (double newValue) {},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildApp(null));
|
||||
|
||||
final RenderBox sliderBox =
|
||||
tester.firstRenderObject<RenderBox>(find.byType(Slider));
|
||||
|
||||
expect(sliderBox, paints..rect(color: theme.accentColor)..rect(color: theme.unselectedWidgetColor));
|
||||
expect(sliderBox, paints..circle(color: theme.accentColor));
|
||||
expect(sliderBox, isNot(paints..circle(color: customColor)));
|
||||
expect(sliderBox, isNot(paints..circle(color: theme.unselectedWidgetColor)));
|
||||
await tester.pumpWidget(buildApp(customColor));
|
||||
expect(sliderBox, paints..rect(color: customColor)..rect(color: theme.unselectedWidgetColor));
|
||||
expect(sliderBox, paints..circle(color: customColor));
|
||||
expect(sliderBox, isNot(paints..circle(color: theme.accentColor)));
|
||||
expect(sliderBox, isNot(paints..circle(color: theme.unselectedWidgetColor)));
|
||||
});
|
||||
|
||||
testWidgets('Slider has a customizable inactive color',
|
||||
(WidgetTester tester) async {
|
||||
final Color customColor = const Color(0xFF4CD964);
|
||||
final ThemeData theme = new ThemeData(platform: TargetPlatform.android);
|
||||
Widget buildApp(Color inactiveColor) {
|
||||
return new Material(
|
||||
child: new Center(
|
||||
child: new Theme(
|
||||
data: theme,
|
||||
child: new Slider(
|
||||
value: 0.5,
|
||||
inactiveColor: inactiveColor,
|
||||
onChanged: (double newValue) {},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildApp(null));
|
||||
|
||||
final RenderBox sliderBox =
|
||||
tester.firstRenderObject<RenderBox>(find.byType(Slider));
|
||||
|
||||
expect(sliderBox, paints..rect(color: theme.accentColor)..rect(color: theme.unselectedWidgetColor));
|
||||
expect(sliderBox, paints..circle(color: theme.accentColor));
|
||||
await tester.pumpWidget(buildApp(customColor));
|
||||
expect(sliderBox, paints..rect(color: theme.accentColor)..rect(color: customColor));
|
||||
expect(sliderBox, paints..circle(color: theme.accentColor));
|
||||
});
|
||||
|
||||
testWidgets('Slider can draw an open thumb at min',
|
||||
(WidgetTester tester) async {
|
||||
Widget buildApp(bool thumbOpenAtMin) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user