Unverified Commit 519a5783 authored by Akshdeep Singh's avatar Akshdeep Singh Committed by GitHub

add material slider secondary value (#109808)

parent 1b8fb4c0
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flutter code sample for Slider
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatefulWidget(),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
double _currentSliderPrimaryValue = 0.2;
double _currentSliderSecondaryValue = 0.5;
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Slider(
value: _currentSliderPrimaryValue,
secondaryTrackValue: _currentSliderSecondaryValue,
label: _currentSliderPrimaryValue.round().toString(),
onChanged: (double value) {
setState(() {
_currentSliderPrimaryValue = value;
});
},
),
Slider(
value: _currentSliderSecondaryValue,
label: _currentSliderSecondaryValue.round().toString(),
onChanged: (double value) {
setState(() {
_currentSliderSecondaryValue = value;
});
},
),
],
);
}
}
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter_api_samples/material/slider/slider.1.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Slider shows secondary track', (WidgetTester tester) async {
await tester.pumpWidget(
const example.MyApp(),
);
expect(find.byType(Slider), findsNWidgets(2));
final Finder slider1Finder = find.byType(Slider).at(0);
final Finder slider2Finder = find.byType(Slider).at(1);
Slider slider1 = tester.widget(slider1Finder);
Slider slider2 = tester.widget(slider2Finder);
expect(slider1.secondaryTrackValue, slider2.value);
const double targetValue = 0.8;
final Rect rect = tester.getRect(slider2Finder);
final Offset target = Offset(rect.left + (rect.right - rect.left) * targetValue, rect.top + (rect.bottom - rect.top) / 2);
await tester.tapAt(target);
await tester.pump();
slider1 = tester.widget(slider1Finder);
slider2 = tester.widget(slider2Finder);
expect(slider1.secondaryTrackValue, closeTo(targetValue, 0.05));
expect(slider1.secondaryTrackValue, slider2.value);
});
}
...@@ -48,6 +48,13 @@ enum _SliderType { material, adaptive } ...@@ -48,6 +48,13 @@ enum _SliderType { material, adaptive }
/// ** See code in examples/api/lib/material/slider/slider.0.dart ** /// ** See code in examples/api/lib/material/slider/slider.0.dart **
/// {@end-tool} /// {@end-tool}
/// ///
/// {@tool dartpad}
/// This example shows a [Slider] widget using the [Slider.secondaryTrackValue]
/// to show a secondary track in the slider.
///
/// ** See code in examples/api/lib/material/slider/slider.1.dart **
/// {@end-tool}
///
/// A slider can be used to select from either a continuous or a discrete set of /// A slider can be used to select from either a continuous or a discrete set of
/// values. The default is to use a continuous range of values from [min] to /// values. The default is to use a continuous range of values from [min] to
/// [max]. To use discrete values, use a non-null value for [divisions], which /// [max]. To use discrete values, use a non-null value for [divisions], which
...@@ -125,6 +132,7 @@ class Slider extends StatefulWidget { ...@@ -125,6 +132,7 @@ class Slider extends StatefulWidget {
const Slider({ const Slider({
super.key, super.key,
required this.value, required this.value,
this.secondaryTrackValue,
required this.onChanged, required this.onChanged,
this.onChangeStart, this.onChangeStart,
this.onChangeEnd, this.onChangeEnd,
...@@ -134,6 +142,7 @@ class Slider extends StatefulWidget { ...@@ -134,6 +142,7 @@ class Slider extends StatefulWidget {
this.label, this.label,
this.activeColor, this.activeColor,
this.inactiveColor, this.inactiveColor,
this.secondaryActiveColor,
this.thumbColor, this.thumbColor,
this.mouseCursor, this.mouseCursor,
this.semanticFormatterCallback, this.semanticFormatterCallback,
...@@ -146,6 +155,8 @@ class Slider extends StatefulWidget { ...@@ -146,6 +155,8 @@ class Slider extends StatefulWidget {
assert(min <= max), assert(min <= max),
assert(value >= min && value <= max, assert(value >= min && value <= max,
'Value $value is not between minimum $min and maximum $max'), 'Value $value is not between minimum $min and maximum $max'),
assert(secondaryTrackValue == null || (secondaryTrackValue >= min && secondaryTrackValue <= max),
'SecondaryValue $secondaryTrackValue is not between $min and $max'),
assert(divisions == null || divisions > 0); assert(divisions == null || divisions > 0);
/// Creates an adaptive [Slider] based on the target platform, following /// Creates an adaptive [Slider] based on the target platform, following
...@@ -155,13 +166,15 @@ class Slider extends StatefulWidget { ...@@ -155,13 +166,15 @@ class Slider extends StatefulWidget {
/// Creates a [CupertinoSlider] if the target platform is iOS or macOS, creates a /// Creates a [CupertinoSlider] if the target platform is iOS or macOS, creates a
/// Material Design slider otherwise. /// Material Design slider otherwise.
/// ///
/// If a [CupertinoSlider] is created, the following parameters are /// If a [CupertinoSlider] is created, the following parameters are ignored:
/// ignored: [label], [inactiveColor], [semanticFormatterCallback]. /// [secondaryTrackValue], [label], [inactiveColor], [secondaryActiveColor],
/// [semanticFormatterCallback].
/// ///
/// The target platform is based on the current [Theme]: [ThemeData.platform]. /// The target platform is based on the current [Theme]: [ThemeData.platform].
const Slider.adaptive({ const Slider.adaptive({
super.key, super.key,
required this.value, required this.value,
this.secondaryTrackValue,
required this.onChanged, required this.onChanged,
this.onChangeStart, this.onChangeStart,
this.onChangeEnd, this.onChangeEnd,
...@@ -172,6 +185,7 @@ class Slider extends StatefulWidget { ...@@ -172,6 +185,7 @@ class Slider extends StatefulWidget {
this.mouseCursor, this.mouseCursor,
this.activeColor, this.activeColor,
this.inactiveColor, this.inactiveColor,
this.secondaryActiveColor,
this.thumbColor, this.thumbColor,
this.semanticFormatterCallback, this.semanticFormatterCallback,
this.focusNode, this.focusNode,
...@@ -181,7 +195,10 @@ class Slider extends StatefulWidget { ...@@ -181,7 +195,10 @@ class Slider extends StatefulWidget {
assert(min != null), assert(min != null),
assert(max != null), assert(max != null),
assert(min <= max), assert(min <= max),
assert(value >= min && value <= max), assert(value >= min && value <= max,
'Value $value is not between minimum $min and maximum $max'),
assert(secondaryTrackValue == null || (secondaryTrackValue >= min && secondaryTrackValue <= max),
'SecondaryValue $secondaryTrackValue is not between $min and $max'),
assert(divisions == null || divisions > 0); assert(divisions == null || divisions > 0);
/// The currently selected value for this slider. /// The currently selected value for this slider.
...@@ -189,6 +206,17 @@ class Slider extends StatefulWidget { ...@@ -189,6 +206,17 @@ class Slider extends StatefulWidget {
/// The slider's thumb is drawn at a position that corresponds to this value. /// The slider's thumb is drawn at a position that corresponds to this value.
final double value; final double value;
/// The secondary track value for this slider.
///
/// If not null, a secondary track using [Slider.secondaryActiveColor] color
/// is drawn between the thumb and this value, over the inactive track.
///
/// If less than [Slider.value], then the secondary track is not shown.
///
/// It can be ideal for media scenarios such as showing the buffering progress
/// while the [Slider.value] shows the play progress.
final double? secondaryTrackValue;
/// Called during a drag when the user is selecting a new value for the slider /// Called during a drag when the user is selecting a new value for the slider
/// by dragging. /// by dragging.
/// ///
...@@ -365,6 +393,18 @@ class Slider extends StatefulWidget { ...@@ -365,6 +393,18 @@ class Slider extends StatefulWidget {
/// Ignored if this slider is created with [Slider.adaptive]. /// Ignored if this slider is created with [Slider.adaptive].
final Color? inactiveColor; final Color? inactiveColor;
/// The color to use for the portion of the slider track between the thumb and
/// the [Slider.secondaryTrackValue].
///
/// Defaults to the [SliderThemeData.secondaryActiveTrackColor] of the current
/// [SliderTheme].
///
/// Using a [SliderTheme] gives much more fine-grained control over the
/// appearance of various components of the slider.
///
/// Ignored if this slider is created with [Slider.adaptive].
final Color? secondaryActiveColor;
/// The color of the thumb. /// The color of the thumb.
/// ///
/// If this color is null: /// If this color is null:
...@@ -443,6 +483,7 @@ class Slider extends StatefulWidget { ...@@ -443,6 +483,7 @@ class Slider extends StatefulWidget {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(DoubleProperty('value', value)); properties.add(DoubleProperty('value', value));
properties.add(DoubleProperty('secondaryTrackValue', secondaryTrackValue));
properties.add(ObjectFlagProperty<ValueChanged<double>>('onChanged', onChanged, ifNull: 'disabled')); properties.add(ObjectFlagProperty<ValueChanged<double>>('onChanged', onChanged, ifNull: 'disabled'));
properties.add(ObjectFlagProperty<ValueChanged<double>>.has('onChangeStart', onChangeStart)); properties.add(ObjectFlagProperty<ValueChanged<double>>.has('onChangeStart', onChangeStart));
properties.add(ObjectFlagProperty<ValueChanged<double>>.has('onChangeEnd', onChangeEnd)); properties.add(ObjectFlagProperty<ValueChanged<double>>.has('onChangeEnd', onChangeEnd));
...@@ -452,6 +493,7 @@ class Slider extends StatefulWidget { ...@@ -452,6 +493,7 @@ class Slider extends StatefulWidget {
properties.add(StringProperty('label', label)); properties.add(StringProperty('label', label));
properties.add(ColorProperty('activeColor', activeColor)); properties.add(ColorProperty('activeColor', activeColor));
properties.add(ColorProperty('inactiveColor', inactiveColor)); properties.add(ColorProperty('inactiveColor', inactiveColor));
properties.add(ColorProperty('secondaryActiveColor', secondaryActiveColor));
properties.add(ObjectFlagProperty<ValueChanged<double>>.has('semanticFormatterCallback', semanticFormatterCallback)); properties.add(ObjectFlagProperty<ValueChanged<double>>.has('semanticFormatterCallback', semanticFormatterCallback));
properties.add(ObjectFlagProperty<FocusNode>.has('focusNode', focusNode)); properties.add(ObjectFlagProperty<FocusNode>.has('focusNode', focusNode));
properties.add(FlagProperty('autofocus', value: autofocus, ifTrue: 'autofocus')); properties.add(FlagProperty('autofocus', value: autofocus, ifTrue: 'autofocus'));
...@@ -708,8 +750,10 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin { ...@@ -708,8 +750,10 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin {
trackHeight: sliderTheme.trackHeight ?? defaultTrackHeight, trackHeight: sliderTheme.trackHeight ?? defaultTrackHeight,
activeTrackColor: widget.activeColor ?? sliderTheme.activeTrackColor ?? theme.colorScheme.primary, activeTrackColor: widget.activeColor ?? sliderTheme.activeTrackColor ?? theme.colorScheme.primary,
inactiveTrackColor: widget.inactiveColor ?? sliderTheme.inactiveTrackColor ?? theme.colorScheme.primary.withOpacity(0.24), inactiveTrackColor: widget.inactiveColor ?? sliderTheme.inactiveTrackColor ?? theme.colorScheme.primary.withOpacity(0.24),
secondaryActiveTrackColor: widget.secondaryActiveColor ?? sliderTheme.secondaryActiveTrackColor ?? theme.colorScheme.primary.withOpacity(0.54),
disabledActiveTrackColor: sliderTheme.disabledActiveTrackColor ?? theme.colorScheme.onSurface.withOpacity(0.32), disabledActiveTrackColor: sliderTheme.disabledActiveTrackColor ?? theme.colorScheme.onSurface.withOpacity(0.32),
disabledInactiveTrackColor: sliderTheme.disabledInactiveTrackColor ?? theme.colorScheme.onSurface.withOpacity(0.12), disabledInactiveTrackColor: sliderTheme.disabledInactiveTrackColor ?? theme.colorScheme.onSurface.withOpacity(0.12),
disabledSecondaryActiveTrackColor: sliderTheme.disabledSecondaryActiveTrackColor ?? theme.colorScheme.onSurface.withOpacity(0.12),
activeTickMarkColor: widget.inactiveColor ?? sliderTheme.activeTickMarkColor ?? theme.colorScheme.onPrimary.withOpacity(0.54), activeTickMarkColor: widget.inactiveColor ?? sliderTheme.activeTickMarkColor ?? theme.colorScheme.onPrimary.withOpacity(0.54),
inactiveTickMarkColor: widget.activeColor ?? sliderTheme.inactiveTickMarkColor ?? theme.colorScheme.primary.withOpacity(0.54), inactiveTickMarkColor: widget.activeColor ?? sliderTheme.inactiveTickMarkColor ?? theme.colorScheme.primary.withOpacity(0.54),
disabledActiveTickMarkColor: sliderTheme.disabledActiveTickMarkColor ?? theme.colorScheme.onPrimary.withOpacity(0.12), disabledActiveTickMarkColor: sliderTheme.disabledActiveTickMarkColor ?? theme.colorScheme.onPrimary.withOpacity(0.12),
...@@ -789,6 +833,7 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin { ...@@ -789,6 +833,7 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin {
child: _SliderRenderObjectWidget( child: _SliderRenderObjectWidget(
key: _renderObjectKey, key: _renderObjectKey,
value: _convert(widget.value), value: _convert(widget.value),
secondaryTrackValue: (widget.secondaryTrackValue != null) ? _convert(widget.secondaryTrackValue!) : null,
divisions: widget.divisions, divisions: widget.divisions,
label: widget.label, label: widget.label,
sliderTheme: sliderTheme, sliderTheme: sliderTheme,
...@@ -852,6 +897,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget { ...@@ -852,6 +897,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
const _SliderRenderObjectWidget({ const _SliderRenderObjectWidget({
super.key, super.key,
required this.value, required this.value,
required this.secondaryTrackValue,
required this.divisions, required this.divisions,
required this.label, required this.label,
required this.sliderTheme, required this.sliderTheme,
...@@ -867,6 +913,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget { ...@@ -867,6 +913,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
}); });
final double value; final double value;
final double? secondaryTrackValue;
final int? divisions; final int? divisions;
final String? label; final String? label;
final SliderThemeData sliderTheme; final SliderThemeData sliderTheme;
...@@ -884,6 +931,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget { ...@@ -884,6 +931,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
_RenderSlider createRenderObject(BuildContext context) { _RenderSlider createRenderObject(BuildContext context) {
return _RenderSlider( return _RenderSlider(
value: value, value: value,
secondaryTrackValue: secondaryTrackValue,
divisions: divisions, divisions: divisions,
label: label, label: label,
sliderTheme: sliderTheme, sliderTheme: sliderTheme,
...@@ -909,6 +957,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget { ...@@ -909,6 +957,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
// setter dependent on the `divisions`. // setter dependent on the `divisions`.
..divisions = divisions ..divisions = divisions
..value = value ..value = value
..secondaryTrackValue = secondaryTrackValue
..label = label ..label = label
..sliderTheme = sliderTheme ..sliderTheme = sliderTheme
..textScaleFactor = textScaleFactor ..textScaleFactor = textScaleFactor
...@@ -930,6 +979,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget { ...@@ -930,6 +979,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
_RenderSlider({ _RenderSlider({
required double value, required double value,
required double? secondaryTrackValue,
required int? divisions, required int? divisions,
required String? label, required String? label,
required SliderThemeData sliderTheme, required SliderThemeData sliderTheme,
...@@ -946,12 +996,14 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -946,12 +996,14 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
required bool hovering, required bool hovering,
required DeviceGestureSettings gestureSettings, required DeviceGestureSettings gestureSettings,
}) : assert(value != null && value >= 0.0 && value <= 1.0), }) : assert(value != null && value >= 0.0 && value <= 1.0),
assert(secondaryTrackValue == null || (secondaryTrackValue >= 0.0 && secondaryTrackValue <= 1.0)),
assert(state != null), assert(state != null),
assert(textDirection != null), assert(textDirection != null),
_platform = platform, _platform = platform,
_semanticFormatterCallback = semanticFormatterCallback, _semanticFormatterCallback = semanticFormatterCallback,
_label = label, _label = label,
_value = value, _value = value,
_secondaryTrackValue = secondaryTrackValue,
_divisions = divisions, _divisions = divisions,
_sliderTheme = sliderTheme, _sliderTheme = sliderTheme,
_textScaleFactor = textScaleFactor, _textScaleFactor = textScaleFactor,
...@@ -1059,6 +1111,17 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -1059,6 +1111,17 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
markNeedsSemanticsUpdate(); markNeedsSemanticsUpdate();
} }
double? get secondaryTrackValue => _secondaryTrackValue;
double? _secondaryTrackValue;
set secondaryTrackValue(double? newValue) {
assert(newValue == null || (newValue >= 0.0 && newValue <= 1.0));
if (newValue == _secondaryTrackValue) {
return;
}
_secondaryTrackValue = newValue;
markNeedsSemanticsUpdate();
}
DeviceGestureSettings? get gestureSettings => _drag.gestureSettings; DeviceGestureSettings? get gestureSettings => _drag.gestureSettings;
set gestureSettings(DeviceGestureSettings? gestureSettings) { set gestureSettings(DeviceGestureSettings? gestureSettings) {
_drag.gestureSettings = gestureSettings; _drag.gestureSettings = gestureSettings;
...@@ -1417,17 +1480,21 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -1417,17 +1480,21 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
@override @override
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
final double value = _state.positionController.value; final double value = _state.positionController.value;
final double? secondaryValue = _secondaryTrackValue;
// The visual position is the position of the thumb from 0 to 1 from left // The visual position is the position of the thumb from 0 to 1 from left
// to right. In left to right, this is the same as the value, but it is // to right. In left to right, this is the same as the value, but it is
// reversed for right to left text. // reversed for right to left text.
final double visualPosition; final double visualPosition;
final double? secondaryVisualPosition;
switch (textDirection) { switch (textDirection) {
case TextDirection.rtl: case TextDirection.rtl:
visualPosition = 1.0 - value; visualPosition = 1.0 - value;
secondaryVisualPosition = (secondaryValue != null) ? (1.0 - secondaryValue) : null;
break; break;
case TextDirection.ltr: case TextDirection.ltr:
visualPosition = value; visualPosition = value;
secondaryVisualPosition = (secondaryValue != null) ? secondaryValue : null;
break; break;
} }
...@@ -1438,6 +1505,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -1438,6 +1505,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
isDiscrete: isDiscrete, isDiscrete: isDiscrete,
); );
final Offset thumbCenter = Offset(trackRect.left + visualPosition * trackRect.width, trackRect.center.dy); final Offset thumbCenter = Offset(trackRect.left + visualPosition * trackRect.width, trackRect.center.dy);
final Offset? secondaryOffset = (secondaryVisualPosition != null) ? Offset(trackRect.left + secondaryVisualPosition * trackRect.width, trackRect.center.dy) : null;
_sliderTheme.trackShape!.paint( _sliderTheme.trackShape!.paint(
context, context,
...@@ -1447,6 +1515,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -1447,6 +1515,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
enableAnimation: _enableAnimation, enableAnimation: _enableAnimation,
textDirection: _textDirection, textDirection: _textDirection,
thumbCenter: thumbCenter, thumbCenter: thumbCenter,
secondaryOffset: secondaryOffset,
isDiscrete: isDiscrete, isDiscrete: isDiscrete,
isEnabled: isInteractive, isEnabled: isInteractive,
); );
......
...@@ -266,8 +266,10 @@ class SliderThemeData with Diagnosticable { ...@@ -266,8 +266,10 @@ class SliderThemeData with Diagnosticable {
this.trackHeight, this.trackHeight,
this.activeTrackColor, this.activeTrackColor,
this.inactiveTrackColor, this.inactiveTrackColor,
this.secondaryActiveTrackColor,
this.disabledActiveTrackColor, this.disabledActiveTrackColor,
this.disabledInactiveTrackColor, this.disabledInactiveTrackColor,
this.disabledSecondaryActiveTrackColor,
this.activeTickMarkColor, this.activeTickMarkColor,
this.inactiveTickMarkColor, this.inactiveTickMarkColor,
this.disabledActiveTickMarkColor, this.disabledActiveTickMarkColor,
...@@ -317,8 +319,10 @@ class SliderThemeData with Diagnosticable { ...@@ -317,8 +319,10 @@ class SliderThemeData with Diagnosticable {
// component Colors (with opacity) from base colors. // component Colors (with opacity) from base colors.
const int activeTrackAlpha = 0xff; const int activeTrackAlpha = 0xff;
const int inactiveTrackAlpha = 0x3d; // 24% opacity const int inactiveTrackAlpha = 0x3d; // 24% opacity
const int secondaryActiveTrackAlpha = 0x8a; // 54% opacity
const int disabledActiveTrackAlpha = 0x52; // 32% opacity const int disabledActiveTrackAlpha = 0x52; // 32% opacity
const int disabledInactiveTrackAlpha = 0x1f; // 12% opacity const int disabledInactiveTrackAlpha = 0x1f; // 12% opacity
const int disabledSecondaryActiveTrackAlpha = 0x1f; // 12% opacity
const int activeTickMarkAlpha = 0x8a; // 54% opacity const int activeTickMarkAlpha = 0x8a; // 54% opacity
const int inactiveTickMarkAlpha = 0x8a; // 54% opacity const int inactiveTickMarkAlpha = 0x8a; // 54% opacity
const int disabledActiveTickMarkAlpha = 0x1f; // 12% opacity const int disabledActiveTickMarkAlpha = 0x1f; // 12% opacity
...@@ -332,8 +336,10 @@ class SliderThemeData with Diagnosticable { ...@@ -332,8 +336,10 @@ class SliderThemeData with Diagnosticable {
trackHeight: 2.0, trackHeight: 2.0,
activeTrackColor: primaryColor.withAlpha(activeTrackAlpha), activeTrackColor: primaryColor.withAlpha(activeTrackAlpha),
inactiveTrackColor: primaryColor.withAlpha(inactiveTrackAlpha), inactiveTrackColor: primaryColor.withAlpha(inactiveTrackAlpha),
secondaryActiveTrackColor: primaryColor.withAlpha(secondaryActiveTrackAlpha),
disabledActiveTrackColor: primaryColorDark.withAlpha(disabledActiveTrackAlpha), disabledActiveTrackColor: primaryColorDark.withAlpha(disabledActiveTrackAlpha),
disabledInactiveTrackColor: primaryColorDark.withAlpha(disabledInactiveTrackAlpha), disabledInactiveTrackColor: primaryColorDark.withAlpha(disabledInactiveTrackAlpha),
disabledSecondaryActiveTrackColor: primaryColorDark.withAlpha(disabledSecondaryActiveTrackAlpha),
activeTickMarkColor: primaryColorLight.withAlpha(activeTickMarkAlpha), activeTickMarkColor: primaryColorLight.withAlpha(activeTickMarkAlpha),
inactiveTickMarkColor: primaryColor.withAlpha(inactiveTickMarkAlpha), inactiveTickMarkColor: primaryColor.withAlpha(inactiveTickMarkAlpha),
disabledActiveTickMarkColor: primaryColorLight.withAlpha(disabledActiveTickMarkAlpha), disabledActiveTickMarkColor: primaryColorLight.withAlpha(disabledActiveTickMarkAlpha),
...@@ -368,10 +374,18 @@ class SliderThemeData with Diagnosticable { ...@@ -368,10 +374,18 @@ class SliderThemeData with Diagnosticable {
/// [Slider.max] position. /// [Slider.max] position.
final Color? inactiveTrackColor; final Color? inactiveTrackColor;
/// The color of the [Slider] track between the current thumb position and the
/// [Slider.secondaryTrackValue] position.
final Color? secondaryActiveTrackColor;
/// The color of the [Slider] track between the [Slider.min] position and the /// The color of the [Slider] track between the [Slider.min] position and the
/// current thumb position when the [Slider] is disabled. /// current thumb position when the [Slider] is disabled.
final Color? disabledActiveTrackColor; final Color? disabledActiveTrackColor;
/// The color of the [Slider] track between the current thumb position and the
/// [Slider.secondaryTrackValue] position when the [Slider] is disabled.
final Color? disabledSecondaryActiveTrackColor;
/// The color of the [Slider] track between the current thumb position and the /// The color of the [Slider] track between the current thumb position and the
/// [Slider.max] position when the [Slider] is disabled. /// [Slider.max] position when the [Slider] is disabled.
final Color? disabledInactiveTrackColor; final Color? disabledInactiveTrackColor;
...@@ -573,8 +587,10 @@ class SliderThemeData with Diagnosticable { ...@@ -573,8 +587,10 @@ class SliderThemeData with Diagnosticable {
double? trackHeight, double? trackHeight,
Color? activeTrackColor, Color? activeTrackColor,
Color? inactiveTrackColor, Color? inactiveTrackColor,
Color? secondaryActiveTrackColor,
Color? disabledActiveTrackColor, Color? disabledActiveTrackColor,
Color? disabledInactiveTrackColor, Color? disabledInactiveTrackColor,
Color? disabledSecondaryActiveTrackColor,
Color? activeTickMarkColor, Color? activeTickMarkColor,
Color? inactiveTickMarkColor, Color? inactiveTickMarkColor,
Color? disabledActiveTickMarkColor, Color? disabledActiveTickMarkColor,
...@@ -603,8 +619,10 @@ class SliderThemeData with Diagnosticable { ...@@ -603,8 +619,10 @@ class SliderThemeData with Diagnosticable {
trackHeight: trackHeight ?? this.trackHeight, trackHeight: trackHeight ?? this.trackHeight,
activeTrackColor: activeTrackColor ?? this.activeTrackColor, activeTrackColor: activeTrackColor ?? this.activeTrackColor,
inactiveTrackColor: inactiveTrackColor ?? this.inactiveTrackColor, inactiveTrackColor: inactiveTrackColor ?? this.inactiveTrackColor,
secondaryActiveTrackColor: secondaryActiveTrackColor ?? this.secondaryActiveTrackColor,
disabledActiveTrackColor: disabledActiveTrackColor ?? this.disabledActiveTrackColor, disabledActiveTrackColor: disabledActiveTrackColor ?? this.disabledActiveTrackColor,
disabledInactiveTrackColor: disabledInactiveTrackColor ?? this.disabledInactiveTrackColor, disabledInactiveTrackColor: disabledInactiveTrackColor ?? this.disabledInactiveTrackColor,
disabledSecondaryActiveTrackColor: disabledSecondaryActiveTrackColor ?? this.disabledSecondaryActiveTrackColor,
activeTickMarkColor: activeTickMarkColor ?? this.activeTickMarkColor, activeTickMarkColor: activeTickMarkColor ?? this.activeTickMarkColor,
inactiveTickMarkColor: inactiveTickMarkColor ?? this.inactiveTickMarkColor, inactiveTickMarkColor: inactiveTickMarkColor ?? this.inactiveTickMarkColor,
disabledActiveTickMarkColor: disabledActiveTickMarkColor ?? this.disabledActiveTickMarkColor, disabledActiveTickMarkColor: disabledActiveTickMarkColor ?? this.disabledActiveTickMarkColor,
...@@ -644,8 +662,10 @@ class SliderThemeData with Diagnosticable { ...@@ -644,8 +662,10 @@ class SliderThemeData with Diagnosticable {
trackHeight: lerpDouble(a.trackHeight, b.trackHeight, t), trackHeight: lerpDouble(a.trackHeight, b.trackHeight, t),
activeTrackColor: Color.lerp(a.activeTrackColor, b.activeTrackColor, t), activeTrackColor: Color.lerp(a.activeTrackColor, b.activeTrackColor, t),
inactiveTrackColor: Color.lerp(a.inactiveTrackColor, b.inactiveTrackColor, t), inactiveTrackColor: Color.lerp(a.inactiveTrackColor, b.inactiveTrackColor, t),
secondaryActiveTrackColor: Color.lerp(a.secondaryActiveTrackColor, b.secondaryActiveTrackColor, t),
disabledActiveTrackColor: Color.lerp(a.disabledActiveTrackColor, b.disabledActiveTrackColor, t), disabledActiveTrackColor: Color.lerp(a.disabledActiveTrackColor, b.disabledActiveTrackColor, t),
disabledInactiveTrackColor: Color.lerp(a.disabledInactiveTrackColor, b.disabledInactiveTrackColor, t), disabledInactiveTrackColor: Color.lerp(a.disabledInactiveTrackColor, b.disabledInactiveTrackColor, t),
disabledSecondaryActiveTrackColor: Color.lerp(a.disabledSecondaryActiveTrackColor, b.disabledSecondaryActiveTrackColor, t),
activeTickMarkColor: Color.lerp(a.activeTickMarkColor, b.activeTickMarkColor, t), activeTickMarkColor: Color.lerp(a.activeTickMarkColor, b.activeTickMarkColor, t),
inactiveTickMarkColor: Color.lerp(a.inactiveTickMarkColor, b.inactiveTickMarkColor, t), inactiveTickMarkColor: Color.lerp(a.inactiveTickMarkColor, b.inactiveTickMarkColor, t),
disabledActiveTickMarkColor: Color.lerp(a.disabledActiveTickMarkColor, b.disabledActiveTickMarkColor, t), disabledActiveTickMarkColor: Color.lerp(a.disabledActiveTickMarkColor, b.disabledActiveTickMarkColor, t),
...@@ -677,8 +697,10 @@ class SliderThemeData with Diagnosticable { ...@@ -677,8 +697,10 @@ class SliderThemeData with Diagnosticable {
trackHeight, trackHeight,
activeTrackColor, activeTrackColor,
inactiveTrackColor, inactiveTrackColor,
secondaryActiveTrackColor,
disabledActiveTrackColor, disabledActiveTrackColor,
disabledInactiveTrackColor, disabledInactiveTrackColor,
disabledSecondaryActiveTrackColor,
activeTickMarkColor, activeTickMarkColor,
inactiveTickMarkColor, inactiveTickMarkColor,
disabledActiveTickMarkColor, disabledActiveTickMarkColor,
...@@ -691,9 +713,9 @@ class SliderThemeData with Diagnosticable { ...@@ -691,9 +713,9 @@ class SliderThemeData with Diagnosticable {
overlayShape, overlayShape,
tickMarkShape, tickMarkShape,
thumbShape, thumbShape,
trackShape,
valueIndicatorShape,
Object.hash( Object.hash(
trackShape,
valueIndicatorShape,
rangeTickMarkShape, rangeTickMarkShape,
rangeThumbShape, rangeThumbShape,
rangeTrackShape, rangeTrackShape,
...@@ -718,8 +740,10 @@ class SliderThemeData with Diagnosticable { ...@@ -718,8 +740,10 @@ class SliderThemeData with Diagnosticable {
&& other.trackHeight == trackHeight && other.trackHeight == trackHeight
&& other.activeTrackColor == activeTrackColor && other.activeTrackColor == activeTrackColor
&& other.inactiveTrackColor == inactiveTrackColor && other.inactiveTrackColor == inactiveTrackColor
&& other.secondaryActiveTrackColor == secondaryActiveTrackColor
&& other.disabledActiveTrackColor == disabledActiveTrackColor && other.disabledActiveTrackColor == disabledActiveTrackColor
&& other.disabledInactiveTrackColor == disabledInactiveTrackColor && other.disabledInactiveTrackColor == disabledInactiveTrackColor
&& other.disabledSecondaryActiveTrackColor == disabledSecondaryActiveTrackColor
&& other.activeTickMarkColor == activeTickMarkColor && other.activeTickMarkColor == activeTickMarkColor
&& other.inactiveTickMarkColor == inactiveTickMarkColor && other.inactiveTickMarkColor == inactiveTickMarkColor
&& other.disabledActiveTickMarkColor == disabledActiveTickMarkColor && other.disabledActiveTickMarkColor == disabledActiveTickMarkColor
...@@ -752,8 +776,10 @@ class SliderThemeData with Diagnosticable { ...@@ -752,8 +776,10 @@ class SliderThemeData with Diagnosticable {
properties.add(DoubleProperty('trackHeight', trackHeight, defaultValue: defaultData.trackHeight)); properties.add(DoubleProperty('trackHeight', trackHeight, defaultValue: defaultData.trackHeight));
properties.add(ColorProperty('activeTrackColor', activeTrackColor, defaultValue: defaultData.activeTrackColor)); properties.add(ColorProperty('activeTrackColor', activeTrackColor, defaultValue: defaultData.activeTrackColor));
properties.add(ColorProperty('inactiveTrackColor', inactiveTrackColor, defaultValue: defaultData.inactiveTrackColor)); properties.add(ColorProperty('inactiveTrackColor', inactiveTrackColor, defaultValue: defaultData.inactiveTrackColor));
properties.add(ColorProperty('secondaryActiveTrackColor', secondaryActiveTrackColor, defaultValue: defaultData.secondaryActiveTrackColor));
properties.add(ColorProperty('disabledActiveTrackColor', disabledActiveTrackColor, defaultValue: defaultData.disabledActiveTrackColor)); properties.add(ColorProperty('disabledActiveTrackColor', disabledActiveTrackColor, defaultValue: defaultData.disabledActiveTrackColor));
properties.add(ColorProperty('disabledInactiveTrackColor', disabledInactiveTrackColor, defaultValue: defaultData.disabledInactiveTrackColor)); properties.add(ColorProperty('disabledInactiveTrackColor', disabledInactiveTrackColor, defaultValue: defaultData.disabledInactiveTrackColor));
properties.add(ColorProperty('disabledSecondaryActiveTrackColor', disabledSecondaryActiveTrackColor, defaultValue: defaultData.disabledSecondaryActiveTrackColor));
properties.add(ColorProperty('activeTickMarkColor', activeTickMarkColor, defaultValue: defaultData.activeTickMarkColor)); properties.add(ColorProperty('activeTickMarkColor', activeTickMarkColor, defaultValue: defaultData.activeTickMarkColor));
properties.add(ColorProperty('inactiveTickMarkColor', inactiveTickMarkColor, defaultValue: defaultData.inactiveTickMarkColor)); properties.add(ColorProperty('inactiveTickMarkColor', inactiveTickMarkColor, defaultValue: defaultData.inactiveTickMarkColor));
properties.add(ColorProperty('disabledActiveTickMarkColor', disabledActiveTickMarkColor, defaultValue: defaultData.disabledActiveTickMarkColor)); properties.add(ColorProperty('disabledActiveTickMarkColor', disabledActiveTickMarkColor, defaultValue: defaultData.disabledActiveTickMarkColor));
...@@ -1047,6 +1073,11 @@ abstract class SliderTrackShape { ...@@ -1047,6 +1073,11 @@ abstract class SliderTrackShape {
/// relative to the origin of the [PaintingContext.canvas]. It can be used as /// relative to the origin of the [PaintingContext.canvas]. It can be used as
/// the point that divides the track into 2 segments. /// 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.
///
/// {@macro flutter.material.SliderTickMarkShape.getPreferredSize.isEnabled} /// {@macro flutter.material.SliderTickMarkShape.getPreferredSize.isEnabled}
/// ///
/// {@macro flutter.material.SliderComponentShape.paint.isDiscrete} /// {@macro flutter.material.SliderComponentShape.paint.isDiscrete}
...@@ -1068,6 +1099,7 @@ abstract class SliderTrackShape { ...@@ -1068,6 +1099,7 @@ abstract class SliderTrackShape {
required SliderThemeData sliderTheme, required SliderThemeData sliderTheme,
required Animation<double> enableAnimation, required Animation<double> enableAnimation,
required Offset thumbCenter, required Offset thumbCenter,
Offset? secondaryOffset,
bool isEnabled, bool isEnabled,
bool isDiscrete, bool isDiscrete,
required TextDirection textDirection, required TextDirection textDirection,
...@@ -1534,6 +1566,7 @@ class RectangularSliderTrackShape extends SliderTrackShape with BaseSliderTrackS ...@@ -1534,6 +1566,7 @@ class RectangularSliderTrackShape extends SliderTrackShape with BaseSliderTrackS
required Animation<double> enableAnimation, required Animation<double> enableAnimation,
required TextDirection textDirection, required TextDirection textDirection,
required Offset thumbCenter, required Offset thumbCenter,
Offset? secondaryOffset,
bool isDiscrete = false, bool isDiscrete = false,
bool isEnabled = false, bool isEnabled = false,
}) { }) {
...@@ -1593,6 +1626,25 @@ class RectangularSliderTrackShape extends SliderTrackShape with BaseSliderTrackS ...@@ -1593,6 +1626,25 @@ class RectangularSliderTrackShape extends SliderTrackShape with BaseSliderTrackS
if (!rightTrackSegment.isEmpty) { if (!rightTrackSegment.isEmpty) {
context.canvas.drawRect(rightTrackSegment, rightTrackPaint); context.canvas.drawRect(rightTrackSegment, rightTrackPaint);
} }
final bool showSecondaryTrack = (secondaryOffset != null) &&
((textDirection == TextDirection.ltr)
? (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)!;
final Rect secondaryTrackSegment = Rect.fromLTRB(
(textDirection == TextDirection.ltr) ? thumbCenter.dx : secondaryOffset.dx,
trackRect.top,
(textDirection == TextDirection.ltr) ? secondaryOffset.dx : thumbCenter.dx,
trackRect.bottom,
);
if (!secondaryTrackSegment.isEmpty) {
context.canvas.drawRect(secondaryTrackSegment, secondaryTrackPaint);
}
}
} }
} }
...@@ -1635,6 +1687,7 @@ class RoundedRectSliderTrackShape extends SliderTrackShape with BaseSliderTrackS ...@@ -1635,6 +1687,7 @@ class RoundedRectSliderTrackShape extends SliderTrackShape with BaseSliderTrackS
required Animation<double> enableAnimation, required Animation<double> enableAnimation,
required TextDirection textDirection, required TextDirection textDirection,
required Offset thumbCenter, required Offset thumbCenter,
Offset? secondaryOffset,
bool isDiscrete = false, bool isDiscrete = false,
bool isEnabled = false, bool isEnabled = false,
double additionalActiveTrackHeight = 2, double additionalActiveTrackHeight = 2,
...@@ -1709,6 +1762,41 @@ class RoundedRectSliderTrackShape extends SliderTrackShape with BaseSliderTrackS ...@@ -1709,6 +1762,41 @@ class RoundedRectSliderTrackShape extends SliderTrackShape with BaseSliderTrackS
), ),
rightTrackPaint, rightTrackPaint,
); );
final bool showSecondaryTrack = (secondaryOffset != null) &&
((textDirection == TextDirection.ltr)
? (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 (textDirection == TextDirection.ltr) {
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,
);
}
}
} }
} }
......
...@@ -631,6 +631,7 @@ void main() { ...@@ -631,6 +631,7 @@ void main() {
try { try {
const Color customColor1 = Color(0xcafefeed); const Color customColor1 = Color(0xcafefeed);
const Color customColor2 = Color(0xdeadbeef); const Color customColor2 = Color(0xdeadbeef);
const Color customColor3 = Color(0xdecaface);
final ThemeData theme = ThemeData( final ThemeData theme = ThemeData(
platform: TargetPlatform.android, platform: TargetPlatform.android,
primarySwatch: Colors.blue, primarySwatch: Colors.blue,
...@@ -647,6 +648,8 @@ void main() { ...@@ -647,6 +648,8 @@ void main() {
overlayColor: Color(0xff000010), overlayColor: Color(0xff000010),
thumbColor: Color(0xff000011), thumbColor: Color(0xff000011),
valueIndicatorColor: Color(0xff000012), valueIndicatorColor: Color(0xff000012),
disabledSecondaryActiveTrackColor: Color(0xff000013),
secondaryActiveTrackColor: Color(0xff000014),
), ),
); );
final SliderThemeData sliderTheme = theme.sliderTheme; final SliderThemeData sliderTheme = theme.sliderTheme;
...@@ -654,6 +657,7 @@ void main() { ...@@ -654,6 +657,7 @@ void main() {
Widget buildApp({ Widget buildApp({
Color? activeColor, Color? activeColor,
Color? inactiveColor, Color? inactiveColor,
Color? secondaryActiveColor,
int? divisions, int? divisions,
bool enabled = true, bool enabled = true,
}) { }) {
...@@ -671,10 +675,12 @@ void main() { ...@@ -671,10 +675,12 @@ void main() {
data: theme, data: theme,
child: Slider( child: Slider(
value: value, value: value,
secondaryTrackValue: 0.75,
label: '$value', label: '$value',
divisions: divisions, divisions: divisions,
activeColor: activeColor, activeColor: activeColor,
inactiveColor: inactiveColor, inactiveColor: inactiveColor,
secondaryActiveColor: secondaryActiveColor,
onChanged: onChanged, onChanged: onChanged,
), ),
), ),
...@@ -690,47 +696,61 @@ void main() { ...@@ -690,47 +696,61 @@ void main() {
final RenderBox valueIndicatorBox = tester.renderObject(find.byType(Overlay)); final RenderBox valueIndicatorBox = tester.renderObject(find.byType(Overlay));
// Check default theme for enabled widget. // Check default theme for enabled widget.
expect(material, paints..rrect(color: sliderTheme.activeTrackColor)..rrect(color: sliderTheme.inactiveTrackColor)); expect(material, paints..rrect(color: sliderTheme.activeTrackColor)..rrect(color: sliderTheme.inactiveTrackColor)..rrect(color: sliderTheme.secondaryActiveTrackColor));
expect(material, paints..shadow(color: const Color(0xff000000))); expect(material, paints..shadow(color: const Color(0xff000000)));
expect(material, paints..circle(color: sliderTheme.thumbColor)); expect(material, paints..circle(color: sliderTheme.thumbColor));
expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledSecondaryActiveTrackColor)));
expect(material, isNot(paints..circle(color: sliderTheme.activeTickMarkColor))); expect(material, isNot(paints..circle(color: sliderTheme.activeTickMarkColor)));
expect(material, isNot(paints..circle(color: sliderTheme.inactiveTickMarkColor))); expect(material, isNot(paints..circle(color: sliderTheme.inactiveTickMarkColor)));
// Test setting only the activeColor. // Test setting only the activeColor.
await tester.pumpWidget(buildApp(activeColor: customColor1)); await tester.pumpWidget(buildApp(activeColor: customColor1));
expect(material, paints..rrect(color: customColor1)..rrect(color: sliderTheme.inactiveTrackColor)); expect(material, paints..rrect(color: customColor1)..rrect(color: sliderTheme.inactiveTrackColor)..rrect(color: sliderTheme.secondaryActiveTrackColor));
expect(material, paints..shadow(color: Colors.black)); expect(material, paints..shadow(color: Colors.black));
expect(material, paints..circle(color: customColor1)); expect(material, paints..circle(color: customColor1));
expect(material, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(material, isNot(paints..circle(color: sliderTheme.thumbColor)));
expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledSecondaryActiveTrackColor)));
// Test setting only the inactiveColor. // Test setting only the inactiveColor.
await tester.pumpWidget(buildApp(inactiveColor: customColor1)); await tester.pumpWidget(buildApp(inactiveColor: customColor1));
expect(material, paints..rrect(color: sliderTheme.activeTrackColor)..rrect(color: customColor1)); expect(material, paints..rrect(color: sliderTheme.activeTrackColor)..rrect(color: customColor1)..rrect(color: sliderTheme.secondaryActiveTrackColor));
expect(material, paints..shadow(color: Colors.black)); expect(material, paints..shadow(color: Colors.black));
expect(material, paints..circle(color: sliderTheme.thumbColor)); expect(material, paints..circle(color: sliderTheme.thumbColor));
expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledSecondaryActiveTrackColor)));
// Test setting both activeColor and inactiveColor. // Test setting only the secondaryActiveColor.
await tester.pumpWidget(buildApp(activeColor: customColor1, inactiveColor: customColor2)); await tester.pumpWidget(buildApp(secondaryActiveColor: customColor1));
expect(material, paints..rrect(color: customColor1)..rrect(color: customColor2)); expect(material, paints..rrect(color: sliderTheme.activeTrackColor)..rrect(color: sliderTheme.inactiveTrackColor)..rrect(color: customColor1));
expect(material, paints..shadow(color: Colors.black));
expect(material, paints..circle(color: sliderTheme.thumbColor));
expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledSecondaryActiveTrackColor)));
// Test setting both activeColor, inactiveColor, and secondaryActiveColor.
await tester.pumpWidget(buildApp(activeColor: customColor1, inactiveColor: customColor2, secondaryActiveColor: customColor3));
expect(material, paints..rrect(color: customColor1)..rrect(color: customColor2)..rrect(color: customColor3));
expect(material, paints..shadow(color: Colors.black)); expect(material, paints..shadow(color: Colors.black));
expect(material, paints..circle(color: customColor1)); expect(material, paints..circle(color: customColor1));
expect(material, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(material, isNot(paints..circle(color: sliderTheme.thumbColor)));
expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledSecondaryActiveTrackColor)));
// Test colors for discrete slider. // Test colors for discrete slider.
await tester.pumpWidget(buildApp(divisions: 3)); await tester.pumpWidget(buildApp(divisions: 3));
expect(material, paints..rrect(color: sliderTheme.activeTrackColor)..rrect(color: sliderTheme.inactiveTrackColor)); expect(material, paints..rrect(color: sliderTheme.activeTrackColor)..rrect(color: sliderTheme.inactiveTrackColor)..rrect(color: sliderTheme.secondaryActiveTrackColor));
expect( expect(
material, material,
paints paints
...@@ -744,14 +764,16 @@ void main() { ...@@ -744,14 +764,16 @@ void main() {
expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledSecondaryActiveTrackColor)));
// Test colors for discrete slider with inactiveColor and activeColor set. // Test colors for discrete slider with inactiveColor and activeColor set.
await tester.pumpWidget(buildApp( await tester.pumpWidget(buildApp(
activeColor: customColor1, activeColor: customColor1,
inactiveColor: customColor2, inactiveColor: customColor2,
secondaryActiveColor: customColor3,
divisions: 3, divisions: 3,
)); ));
expect(material, paints..rrect(color: customColor1)..rrect(color: customColor2)); expect(material, paints..rrect(color: customColor1)..rrect(color: customColor2)..rrect(color: customColor3));
expect( expect(
material, material,
paints paints
...@@ -766,6 +788,7 @@ void main() { ...@@ -766,6 +788,7 @@ void main() {
expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); expect(material, isNot(paints..circle(color: sliderTheme.disabledThumbColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.disabledSecondaryActiveTrackColor)));
expect(material, isNot(paints..circle(color: sliderTheme.activeTickMarkColor))); expect(material, isNot(paints..circle(color: sliderTheme.activeTickMarkColor)));
expect(material, isNot(paints..circle(color: sliderTheme.inactiveTickMarkColor))); expect(material, isNot(paints..circle(color: sliderTheme.inactiveTickMarkColor)));
...@@ -776,25 +799,29 @@ void main() { ...@@ -776,25 +799,29 @@ void main() {
material, material,
paints paints
..rrect(color: sliderTheme.disabledActiveTrackColor) ..rrect(color: sliderTheme.disabledActiveTrackColor)
..rrect(color: sliderTheme.disabledInactiveTrackColor), ..rrect(color: sliderTheme.disabledInactiveTrackColor)
..rrect(color: sliderTheme.disabledSecondaryActiveTrackColor),
); );
expect(material, paints..shadow(color: Colors.black)..circle(color: sliderTheme.disabledThumbColor)); expect(material, paints..shadow(color: Colors.black)..circle(color: sliderTheme.disabledThumbColor));
expect(material, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(material, isNot(paints..circle(color: sliderTheme.thumbColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.activeTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.activeTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.inactiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.inactiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.secondaryActiveTrackColor)));
// Test setting the activeColor and inactiveColor for disabled widget. // Test setting the activeColor, inactiveColor and secondaryActiveColor for disabled widget.
await tester.pumpWidget(buildApp(activeColor: customColor1, inactiveColor: customColor2, enabled: false)); await tester.pumpWidget(buildApp(activeColor: customColor1, inactiveColor: customColor2, secondaryActiveColor: customColor3, enabled: false));
expect( expect(
material, material,
paints paints
..rrect(color: sliderTheme.disabledActiveTrackColor) ..rrect(color: sliderTheme.disabledActiveTrackColor)
..rrect(color: sliderTheme.disabledInactiveTrackColor), ..rrect(color: sliderTheme.disabledInactiveTrackColor)
..rrect(color: sliderTheme.disabledSecondaryActiveTrackColor),
); );
expect(material, paints..circle(color: sliderTheme.disabledThumbColor)); expect(material, paints..circle(color: sliderTheme.disabledThumbColor));
expect(material, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(material, isNot(paints..circle(color: sliderTheme.thumbColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.activeTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.activeTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.inactiveTrackColor))); expect(material, isNot(paints..rrect(color: sliderTheme.inactiveTrackColor)));
expect(material, isNot(paints..rrect(color: sliderTheme.secondaryActiveTrackColor)));
// Test that the default value indicator has the right colors. // Test that the default value indicator has the right colors.
await tester.pumpWidget(buildApp(divisions: 3)); await tester.pumpWidget(buildApp(divisions: 3));
...@@ -2813,10 +2840,12 @@ void main() { ...@@ -2813,10 +2840,12 @@ void main() {
activeColor: Colors.blue, activeColor: Colors.blue,
divisions: 10, divisions: 10,
inactiveColor: Colors.grey, inactiveColor: Colors.grey,
secondaryActiveColor: Colors.blueGrey,
label: 'Set a value', label: 'Set a value',
max: 100.0, max: 100.0,
onChanged: null, onChanged: null,
value: 50.0, value: 50.0,
secondaryTrackValue: 75.0,
).debugFillProperties(builder); ).debugFillProperties(builder);
final List<String> description = builder.properties final List<String> description = builder.properties
...@@ -2825,6 +2854,7 @@ void main() { ...@@ -2825,6 +2854,7 @@ void main() {
expect(description, <String>[ expect(description, <String>[
'value: 50.0', 'value: 50.0',
'secondaryTrackValue: 75.0',
'disabled', 'disabled',
'min: 0.0', 'min: 0.0',
'max: 100.0', 'max: 100.0',
...@@ -2832,6 +2862,7 @@ void main() { ...@@ -2832,6 +2862,7 @@ void main() {
'label: "Set a value"', 'label: "Set a value"',
'activeColor: MaterialColor(primary value: Color(0xff2196f3))', 'activeColor: MaterialColor(primary value: Color(0xff2196f3))',
'inactiveColor: MaterialColor(primary value: Color(0xff9e9e9e))', 'inactiveColor: MaterialColor(primary value: Color(0xff9e9e9e))',
'secondaryActiveColor: MaterialColor(primary value: Color(0xff607d8b))',
]); ]);
}); });
......
...@@ -34,17 +34,19 @@ void main() { ...@@ -34,17 +34,19 @@ void main() {
trackHeight: 7.0, trackHeight: 7.0,
activeTrackColor: Color(0xFF000001), activeTrackColor: Color(0xFF000001),
inactiveTrackColor: Color(0xFF000002), inactiveTrackColor: Color(0xFF000002),
disabledActiveTrackColor: Color(0xFF000003), secondaryActiveTrackColor: Color(0xFF000003),
disabledInactiveTrackColor: Color(0xFF000004), disabledActiveTrackColor: Color(0xFF000004),
activeTickMarkColor: Color(0xFF000005), disabledInactiveTrackColor: Color(0xFF000005),
inactiveTickMarkColor: Color(0xFF000006), disabledSecondaryActiveTrackColor: Color(0xFF000006),
disabledActiveTickMarkColor: Color(0xFF000007), activeTickMarkColor: Color(0xFF000007),
disabledInactiveTickMarkColor: Color(0xFF000008), inactiveTickMarkColor: Color(0xFF000008),
thumbColor: Color(0xFF000009), disabledActiveTickMarkColor: Color(0xFF000009),
overlappingShapeStrokeColor: Color(0xFF000010), disabledInactiveTickMarkColor: Color(0xFF000010),
disabledThumbColor: Color(0xFF000011), thumbColor: Color(0xFF000011),
overlayColor: Color(0xFF000012), overlappingShapeStrokeColor: Color(0xFF000012),
valueIndicatorColor: Color(0xFF000013), disabledThumbColor: Color(0xFF000013),
overlayColor: Color(0xFF000014),
valueIndicatorColor: Color(0xFF000015),
overlayShape: RoundSliderOverlayShape(), overlayShape: RoundSliderOverlayShape(),
tickMarkShape: RoundSliderTickMarkShape(), tickMarkShape: RoundSliderTickMarkShape(),
thumbShape: RoundSliderThumbShape(), thumbShape: RoundSliderThumbShape(),
...@@ -68,17 +70,19 @@ void main() { ...@@ -68,17 +70,19 @@ void main() {
'trackHeight: 7.0', 'trackHeight: 7.0',
'activeTrackColor: Color(0xff000001)', 'activeTrackColor: Color(0xff000001)',
'inactiveTrackColor: Color(0xff000002)', 'inactiveTrackColor: Color(0xff000002)',
'disabledActiveTrackColor: Color(0xff000003)', 'secondaryActiveTrackColor: Color(0xff000003)',
'disabledInactiveTrackColor: Color(0xff000004)', 'disabledActiveTrackColor: Color(0xff000004)',
'activeTickMarkColor: Color(0xff000005)', 'disabledInactiveTrackColor: Color(0xff000005)',
'inactiveTickMarkColor: Color(0xff000006)', 'disabledSecondaryActiveTrackColor: Color(0xff000006)',
'disabledActiveTickMarkColor: Color(0xff000007)', 'activeTickMarkColor: Color(0xff000007)',
'disabledInactiveTickMarkColor: Color(0xff000008)', 'inactiveTickMarkColor: Color(0xff000008)',
'thumbColor: Color(0xff000009)', 'disabledActiveTickMarkColor: Color(0xff000009)',
'overlappingShapeStrokeColor: Color(0xff000010)', 'disabledInactiveTickMarkColor: Color(0xff000010)',
'disabledThumbColor: Color(0xff000011)', 'thumbColor: Color(0xff000011)',
'overlayColor: Color(0xff000012)', 'overlappingShapeStrokeColor: Color(0xff000012)',
'valueIndicatorColor: Color(0xff000013)', 'disabledThumbColor: Color(0xff000013)',
'overlayColor: Color(0xff000014)',
'valueIndicatorColor: Color(0xff000015)',
"overlayShape: Instance of 'RoundSliderOverlayShape'", "overlayShape: Instance of 'RoundSliderOverlayShape'",
"tickMarkShape: Instance of 'RoundSliderTickMarkShape'", "tickMarkShape: Instance of 'RoundSliderTickMarkShape'",
"thumbShape: Instance of 'RoundSliderThumbShape'", "thumbShape: Instance of 'RoundSliderThumbShape'",
...@@ -103,16 +107,18 @@ void main() { ...@@ -103,16 +107,18 @@ void main() {
final SliderThemeData customTheme = sliderTheme.copyWith( final SliderThemeData customTheme = sliderTheme.copyWith(
activeTrackColor: Colors.purple, activeTrackColor: Colors.purple,
inactiveTrackColor: Colors.purple.withAlpha(0x3d), inactiveTrackColor: Colors.purple.withAlpha(0x3d),
secondaryActiveTrackColor: Colors.purple.withAlpha(0x8a),
); );
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.5, enabled: false)); await tester.pumpWidget(_buildApp(sliderTheme, value: 0.5, secondaryTrackValue: 0.75, enabled: false));
final MaterialInkController material = Material.of(tester.element(find.byType(Slider)))!; final MaterialInkController material = Material.of(tester.element(find.byType(Slider)))!;
expect( expect(
material, material,
paints paints
..rrect(color: customTheme.disabledActiveTrackColor) ..rrect(color: customTheme.disabledActiveTrackColor)
..rrect(color: customTheme.disabledInactiveTrackColor), ..rrect(color: customTheme.disabledInactiveTrackColor)
..rrect(color: customTheme.disabledSecondaryActiveTrackColor),
); );
}); });
...@@ -125,16 +131,18 @@ void main() { ...@@ -125,16 +131,18 @@ void main() {
final SliderThemeData customTheme = sliderTheme.copyWith( final SliderThemeData customTheme = sliderTheme.copyWith(
activeTrackColor: Colors.purple, activeTrackColor: Colors.purple,
inactiveTrackColor: Colors.purple.withAlpha(0x3d), inactiveTrackColor: Colors.purple.withAlpha(0x3d),
secondaryActiveTrackColor: Colors.purple.withAlpha(0x8a),
); );
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.5, enabled: false)); await tester.pumpWidget(_buildApp(sliderTheme, value: 0.5, secondaryTrackValue: 0.75, enabled: false));
final MaterialInkController material = Material.of(tester.element(find.byType(Slider)))!; final MaterialInkController material = Material.of(tester.element(find.byType(Slider)))!;
expect( expect(
material, material,
paints paints
..rrect(color: customTheme.disabledActiveTrackColor) ..rrect(color: customTheme.disabledActiveTrackColor)
..rrect(color: customTheme.disabledInactiveTrackColor), ..rrect(color: customTheme.disabledInactiveTrackColor)
..rrect(color: customTheme.disabledSecondaryActiveTrackColor),
); );
}); });
...@@ -153,8 +161,10 @@ void main() { ...@@ -153,8 +161,10 @@ void main() {
expect(sliderTheme.activeTrackColor, equals(customColor1.withAlpha(0xff))); expect(sliderTheme.activeTrackColor, equals(customColor1.withAlpha(0xff)));
expect(sliderTheme.inactiveTrackColor, equals(customColor1.withAlpha(0x3d))); expect(sliderTheme.inactiveTrackColor, equals(customColor1.withAlpha(0x3d)));
expect(sliderTheme.secondaryActiveTrackColor, equals(customColor1.withAlpha(0x8a)));
expect(sliderTheme.disabledActiveTrackColor, equals(customColor2.withAlpha(0x52))); expect(sliderTheme.disabledActiveTrackColor, equals(customColor2.withAlpha(0x52)));
expect(sliderTheme.disabledInactiveTrackColor, equals(customColor2.withAlpha(0x1f))); expect(sliderTheme.disabledInactiveTrackColor, equals(customColor2.withAlpha(0x1f)));
expect(sliderTheme.disabledSecondaryActiveTrackColor, equals(customColor2.withAlpha(0x1f)));
expect(sliderTheme.activeTickMarkColor, equals(customColor3.withAlpha(0x8a))); expect(sliderTheme.activeTickMarkColor, equals(customColor3.withAlpha(0x8a)));
expect(sliderTheme.inactiveTickMarkColor, equals(customColor1.withAlpha(0x8a))); expect(sliderTheme.inactiveTickMarkColor, equals(customColor1.withAlpha(0x8a)));
expect(sliderTheme.disabledActiveTickMarkColor, equals(customColor3.withAlpha(0x1f))); expect(sliderTheme.disabledActiveTickMarkColor, equals(customColor3.withAlpha(0x1f)));
...@@ -209,8 +219,10 @@ void main() { ...@@ -209,8 +219,10 @@ void main() {
expect(lerp.trackHeight, equals(4.0)); expect(lerp.trackHeight, equals(4.0));
expect(lerp.activeTrackColor, equals(middleGrey.withAlpha(0xff))); expect(lerp.activeTrackColor, equals(middleGrey.withAlpha(0xff)));
expect(lerp.inactiveTrackColor, equals(middleGrey.withAlpha(0x3d))); expect(lerp.inactiveTrackColor, equals(middleGrey.withAlpha(0x3d)));
expect(lerp.secondaryActiveTrackColor, equals(middleGrey.withAlpha(0x8a)));
expect(lerp.disabledActiveTrackColor, equals(middleGrey.withAlpha(0x52))); expect(lerp.disabledActiveTrackColor, equals(middleGrey.withAlpha(0x52)));
expect(lerp.disabledInactiveTrackColor, equals(middleGrey.withAlpha(0x1f))); expect(lerp.disabledInactiveTrackColor, equals(middleGrey.withAlpha(0x1f)));
expect(lerp.disabledSecondaryActiveTrackColor, equals(middleGrey.withAlpha(0x1f)));
expect(lerp.activeTickMarkColor, equals(middleGrey.withAlpha(0x8a))); expect(lerp.activeTickMarkColor, equals(middleGrey.withAlpha(0x8a)));
expect(lerp.inactiveTickMarkColor, equals(middleGrey.withAlpha(0x8a))); expect(lerp.inactiveTickMarkColor, equals(middleGrey.withAlpha(0x8a)));
expect(lerp.disabledActiveTickMarkColor, equals(middleGrey.withAlpha(0x1f))); expect(lerp.disabledActiveTickMarkColor, equals(middleGrey.withAlpha(0x1f)));
...@@ -229,7 +241,7 @@ void main() { ...@@ -229,7 +241,7 @@ void main() {
); );
final SliderThemeData sliderTheme = theme.sliderTheme.copyWith(thumbColor: Colors.red.shade500); final SliderThemeData sliderTheme = theme.sliderTheme.copyWith(thumbColor: Colors.red.shade500);
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25)); await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, secondaryTrackValue: 0.5));
final MaterialInkController material = Material.of(tester.element(find.byType(Slider)))!; final MaterialInkController material = Material.of(tester.element(find.byType(Slider)))!;
const Radius radius = Radius.circular(2); const Radius radius = Radius.circular(2);
...@@ -241,10 +253,11 @@ void main() { ...@@ -241,10 +253,11 @@ void main() {
material, material,
paints paints
..rrect(rrect: RRect.fromLTRBAndCorners(24.0, 297.0, 212.0, 303.0, topLeft: activatedRadius, bottomLeft: activatedRadius), color: sliderTheme.activeTrackColor) ..rrect(rrect: RRect.fromLTRBAndCorners(24.0, 297.0, 212.0, 303.0, topLeft: activatedRadius, bottomLeft: activatedRadius), color: sliderTheme.activeTrackColor)
..rrect(rrect: RRect.fromLTRBAndCorners(212.0, 298.0, 776.0, 302.0, topRight: radius, bottomRight: radius), color: sliderTheme.inactiveTrackColor), ..rrect(rrect: RRect.fromLTRBAndCorners(212.0, 298.0, 776.0, 302.0, topRight: radius, bottomRight: radius), color: sliderTheme.inactiveTrackColor)
..rrect(rrect: RRect.fromLTRBAndCorners(212.0, 298.0, 400.0, 302.0, topRight: radius, bottomRight: radius), color: sliderTheme.secondaryActiveTrackColor),
); );
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, enabled: false)); await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, secondaryTrackValue: 0.5, enabled: false));
await tester.pumpAndSettle(); // wait for disable animation await tester.pumpAndSettle(); // wait for disable animation
// The disabled slider thumb is the same size as the enabled thumb. // The disabled slider thumb is the same size as the enabled thumb.
...@@ -252,7 +265,8 @@ void main() { ...@@ -252,7 +265,8 @@ void main() {
material, material,
paints paints
..rrect(rrect: RRect.fromLTRBAndCorners(24.0, 297.0, 212.0, 303.0, topLeft: activatedRadius, bottomLeft: activatedRadius), color: sliderTheme.disabledActiveTrackColor) ..rrect(rrect: RRect.fromLTRBAndCorners(24.0, 297.0, 212.0, 303.0, topLeft: activatedRadius, bottomLeft: activatedRadius), color: sliderTheme.disabledActiveTrackColor)
..rrect(rrect: RRect.fromLTRBAndCorners(212.0, 298.0, 776.0, 302.0, topRight: radius, bottomRight: radius), color: sliderTheme.disabledInactiveTrackColor), ..rrect(rrect: RRect.fromLTRBAndCorners(212.0, 298.0, 776.0, 302.0, topRight: radius, bottomRight: radius), color: sliderTheme.disabledInactiveTrackColor)
..rrect(rrect: RRect.fromLTRBAndCorners(212.0, 298.0, 400.0, 302.0, topRight: radius, bottomRight: radius), color: sliderTheme.disabledSecondaryActiveTrackColor),
); );
}); });
...@@ -1348,17 +1362,19 @@ class RoundedRectSliderTrackShapeWithCustomAdditionalActiveTrackHeight extends R ...@@ -1348,17 +1362,19 @@ class RoundedRectSliderTrackShapeWithCustomAdditionalActiveTrackHeight extends R
required Animation<double> enableAnimation, required Animation<double> enableAnimation,
required TextDirection textDirection, required TextDirection textDirection,
required Offset thumbCenter, required Offset thumbCenter,
Offset? secondaryOffset,
bool isDiscrete = false, bool isDiscrete = false,
bool isEnabled = false, bool isEnabled = false,
double additionalActiveTrackHeight = 2.0, double additionalActiveTrackHeight = 2.0,
}) { }) {
super.paint(context, offset, parentBox: parentBox, sliderTheme: sliderTheme, enableAnimation: enableAnimation, textDirection: textDirection, thumbCenter: thumbCenter, additionalActiveTrackHeight: this.additionalActiveTrackHeight); super.paint(context, offset, parentBox: parentBox, sliderTheme: sliderTheme, enableAnimation: enableAnimation, textDirection: textDirection, thumbCenter: thumbCenter, secondaryOffset: secondaryOffset, additionalActiveTrackHeight: this.additionalActiveTrackHeight);
} }
} }
Widget _buildApp( Widget _buildApp(
SliderThemeData sliderTheme, { SliderThemeData sliderTheme, {
double value = 0.0, double value = 0.0,
double? secondaryTrackValue,
bool enabled = true, bool enabled = true,
int? divisions, int? divisions,
}) { }) {
...@@ -1370,6 +1386,7 @@ Widget _buildApp( ...@@ -1370,6 +1386,7 @@ Widget _buildApp(
data: sliderTheme, data: sliderTheme,
child: Slider( child: Slider(
value: value, value: value,
secondaryTrackValue: secondaryTrackValue,
label: '$value', label: '$value',
onChanged: onChanged, onChanged: onChanged,
divisions: divisions, divisions: divisions,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment