Add a slider demo, and a text theme for SliderThemeData (#15620)
This adds a slider demo with a custom theme to the gallery. In the process of adding this, I decided to add a text theme to the SliderThemeData, since it's a pain to change the text style on the value indicator otherwise.
This commit is contained in:
parent
7a2853012f
commit
10fe2056f3
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SliderDemo extends StatefulWidget {
|
||||
@ -11,12 +13,124 @@ class SliderDemo extends StatefulWidget {
|
||||
_SliderDemoState createState() => new _SliderDemoState();
|
||||
}
|
||||
|
||||
Path _triangle(double size, Offset thumbCenter, {bool invert: false}) {
|
||||
final Path thumbPath = new Path();
|
||||
final double height = math.sqrt(3.0) / 2.0;
|
||||
final double halfSide = size / 2.0;
|
||||
final double centerHeight = size * height / 3.0;
|
||||
final double sign = invert ? -1.0 : 1.0;
|
||||
thumbPath.moveTo(thumbCenter.dx - halfSide, thumbCenter.dy + sign * centerHeight);
|
||||
thumbPath.lineTo(thumbCenter.dx, thumbCenter.dy - 2.0 * sign * centerHeight);
|
||||
thumbPath.lineTo(thumbCenter.dx + halfSide, thumbCenter.dy + sign * centerHeight);
|
||||
thumbPath.close();
|
||||
return thumbPath;
|
||||
}
|
||||
|
||||
class _CustomThumbShape extends SliderComponentShape {
|
||||
static const double _thumbSize = 4.0;
|
||||
static const double _disabledThumbSize = 3.0;
|
||||
|
||||
@override
|
||||
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
|
||||
return isEnabled ? const Size.fromRadius(_thumbSize) : const Size.fromRadius(_disabledThumbSize);
|
||||
}
|
||||
|
||||
static final Tween<double> sizeTween = new Tween<double>(
|
||||
begin: _disabledThumbSize,
|
||||
end: _thumbSize,
|
||||
);
|
||||
|
||||
@override
|
||||
void paint(
|
||||
PaintingContext context,
|
||||
Offset thumbCenter, {
|
||||
Animation<double> activationAnimation,
|
||||
Animation<double> enableAnimation,
|
||||
bool isDiscrete,
|
||||
TextPainter labelPainter,
|
||||
RenderBox parentBox,
|
||||
SliderThemeData sliderTheme,
|
||||
TextDirection textDirection,
|
||||
double value,
|
||||
}) {
|
||||
final Canvas canvas = context.canvas;
|
||||
final ColorTween colorTween = new ColorTween(
|
||||
begin: sliderTheme.disabledThumbColor,
|
||||
end: sliderTheme.thumbColor,
|
||||
);
|
||||
final double size = _thumbSize * sizeTween.evaluate(enableAnimation);
|
||||
final Path thumbPath = _triangle(size, thumbCenter);
|
||||
canvas.drawPath(thumbPath, new Paint()..color = colorTween.evaluate(enableAnimation));
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomValueIndicatorShape extends SliderComponentShape {
|
||||
static const double _indicatorSize = 4.0;
|
||||
static const double _disabledIndicatorSize = 3.0;
|
||||
static const double _slideUpHeight = 40.0;
|
||||
|
||||
@override
|
||||
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
|
||||
return new Size.fromRadius(isEnabled ? _indicatorSize : _disabledIndicatorSize);
|
||||
}
|
||||
|
||||
static final Tween<double> sizeTween = new Tween<double>(
|
||||
begin: _disabledIndicatorSize,
|
||||
end: _indicatorSize,
|
||||
);
|
||||
|
||||
@override
|
||||
void paint(
|
||||
PaintingContext context,
|
||||
Offset thumbCenter, {
|
||||
Animation<double> activationAnimation,
|
||||
Animation<double> enableAnimation,
|
||||
bool isDiscrete,
|
||||
TextPainter labelPainter,
|
||||
RenderBox parentBox,
|
||||
SliderThemeData sliderTheme,
|
||||
TextDirection textDirection,
|
||||
double value,
|
||||
}) {
|
||||
final Canvas canvas = context.canvas;
|
||||
final ColorTween enableColor = new ColorTween(
|
||||
begin: sliderTheme.disabledThumbColor,
|
||||
end: sliderTheme.valueIndicatorColor,
|
||||
);
|
||||
final Tween<double> slideUpTween = new Tween<double>(
|
||||
begin: 0.0,
|
||||
end: _slideUpHeight,
|
||||
);
|
||||
final double size = _indicatorSize * sizeTween.evaluate(enableAnimation);
|
||||
final Offset slideUpOffset = new Offset(0.0, -slideUpTween.evaluate(activationAnimation));
|
||||
final Path thumbPath = _triangle(
|
||||
size,
|
||||
thumbCenter + slideUpOffset,
|
||||
invert: true,
|
||||
);
|
||||
final Color paintColor = enableColor.evaluate(enableAnimation).withAlpha((255.0 * activationAnimation.value).round());
|
||||
canvas.drawPath(
|
||||
thumbPath,
|
||||
new Paint()..color = paintColor,
|
||||
);
|
||||
canvas.drawLine(
|
||||
thumbCenter,
|
||||
thumbCenter + slideUpOffset,
|
||||
new Paint()
|
||||
..color = paintColor
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 2.0);
|
||||
labelPainter.paint(canvas, thumbCenter + slideUpOffset + new Offset(-labelPainter.width / 2.0, -labelPainter.height - 4.0));
|
||||
}
|
||||
}
|
||||
|
||||
class _SliderDemoState extends State<SliderDemo> {
|
||||
double _value = 25.0;
|
||||
double _discreteValue = 20.0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
return new Scaffold(
|
||||
appBar: new AppBar(title: const Text('Sliders')),
|
||||
body: new Padding(
|
||||
@ -26,7 +140,7 @@ class _SliderDemoState extends State<SliderDemo> {
|
||||
children: <Widget>[
|
||||
new Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget> [
|
||||
children: <Widget>[
|
||||
new Slider(
|
||||
value: _value,
|
||||
min: 0.0,
|
||||
@ -35,21 +149,21 @@ class _SliderDemoState extends State<SliderDemo> {
|
||||
setState(() {
|
||||
_value = value;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
const Text('Continuous'),
|
||||
]
|
||||
],
|
||||
),
|
||||
new Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: const <Widget> [
|
||||
children: const <Widget>[
|
||||
const Slider(value: 0.25, onChanged: null),
|
||||
const Text('Disabled'),
|
||||
]
|
||||
],
|
||||
),
|
||||
new Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget> [
|
||||
children: <Widget>[
|
||||
new Slider(
|
||||
value: _discreteValue,
|
||||
min: 0.0,
|
||||
@ -60,11 +174,43 @@ class _SliderDemoState extends State<SliderDemo> {
|
||||
setState(() {
|
||||
_discreteValue = value;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
const Text('Discrete'),
|
||||
],
|
||||
),
|
||||
new Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
new SliderTheme(
|
||||
data: theme.sliderTheme.copyWith(
|
||||
activeRailColor: Colors.deepPurple,
|
||||
inactiveRailColor: Colors.black26,
|
||||
activeTickMarkColor: Colors.white70,
|
||||
inactiveTickMarkColor: Colors.black,
|
||||
overlayColor: Colors.black12,
|
||||
thumbColor: Colors.deepPurple,
|
||||
valueIndicatorColor: Colors.deepPurpleAccent,
|
||||
thumbShape: new _CustomThumbShape(),
|
||||
valueIndicatorShape: new _CustomValueIndicatorShape(),
|
||||
valueIndicatorTextStyle: theme.accentTextTheme.body2.copyWith(color: Colors.black87),
|
||||
),
|
||||
child: new Slider(
|
||||
value: _discreteValue,
|
||||
min: 0.0,
|
||||
max: 100.0,
|
||||
divisions: 5,
|
||||
label: '${_discreteValue.round()}',
|
||||
onChanged: (double value) {
|
||||
setState(() {
|
||||
_discreteValue = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
const Text('Discrete with Custom Theme'),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -578,7 +578,10 @@ class _RenderSlider extends RenderBox {
|
||||
void _updateLabelPainter() {
|
||||
if (label != null) {
|
||||
_labelPainter
|
||||
..text = new TextSpan(style: _theme.accentTextTheme.body2, text: label)
|
||||
..text = new TextSpan(
|
||||
style: _sliderTheme.valueIndicatorTextStyle,
|
||||
text: label,
|
||||
)
|
||||
..textDirection = textDirection
|
||||
..textScaleFactor = _mediaQueryData.textScaleFactor
|
||||
..layout();
|
||||
@ -849,31 +852,31 @@ class _RenderSlider extends RenderBox {
|
||||
_valueIndicatorAnimation.status != AnimationStatus.dismissed) {
|
||||
if (showValueIndicator) {
|
||||
_sliderTheme.valueIndicatorShape.paint(
|
||||
this,
|
||||
context,
|
||||
isDiscrete,
|
||||
thumbCenter,
|
||||
_valueIndicatorAnimation,
|
||||
_enableAnimation,
|
||||
_labelPainter,
|
||||
_sliderTheme,
|
||||
_textDirection,
|
||||
value,
|
||||
activationAnimation: _valueIndicatorAnimation,
|
||||
enableAnimation: _enableAnimation,
|
||||
isDiscrete: isDiscrete,
|
||||
labelPainter: _labelPainter,
|
||||
parentBox: this,
|
||||
sliderTheme: _sliderTheme,
|
||||
textDirection: _textDirection,
|
||||
value: _value,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_sliderTheme.thumbShape.paint(
|
||||
this,
|
||||
context,
|
||||
isDiscrete,
|
||||
thumbCenter,
|
||||
_overlayAnimation,
|
||||
_enableAnimation,
|
||||
label != null ? _labelPainter : null,
|
||||
_sliderTheme,
|
||||
_textDirection,
|
||||
value,
|
||||
activationAnimation: _valueIndicatorAnimation,
|
||||
enableAnimation: _enableAnimation,
|
||||
isDiscrete: isDiscrete,
|
||||
labelPainter: _labelPainter,
|
||||
parentBox: this,
|
||||
sliderTheme: _sliderTheme,
|
||||
textDirection: _textDirection,
|
||||
value: _value,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,9 @@ class SliderTheme extends InheritedWidget {
|
||||
Key key,
|
||||
@required this.data,
|
||||
@required Widget child,
|
||||
}) : assert(child != null),
|
||||
assert(data != null),
|
||||
super(key: key, child: child);
|
||||
}) : assert(child != null),
|
||||
assert(data != null),
|
||||
super(key: key, child: child);
|
||||
|
||||
/// Specifies the color and shape values for descendant slider widgets.
|
||||
final SliderThemeData data;
|
||||
@ -194,21 +194,23 @@ class SliderThemeData extends Diagnosticable {
|
||||
@required this.thumbShape,
|
||||
@required this.valueIndicatorShape,
|
||||
@required this.showValueIndicator,
|
||||
}) : assert(activeRailColor != null),
|
||||
assert(inactiveRailColor != null),
|
||||
assert(disabledActiveRailColor != null),
|
||||
assert(disabledInactiveRailColor != null),
|
||||
assert(activeTickMarkColor != null),
|
||||
assert(inactiveTickMarkColor != null),
|
||||
assert(disabledActiveTickMarkColor != null),
|
||||
assert(disabledInactiveTickMarkColor != null),
|
||||
assert(thumbColor != null),
|
||||
assert(disabledThumbColor != null),
|
||||
assert(overlayColor != null),
|
||||
assert(valueIndicatorColor != null),
|
||||
assert(thumbShape != null),
|
||||
assert(valueIndicatorShape != null),
|
||||
assert(showValueIndicator != null);
|
||||
@required this.valueIndicatorTextStyle,
|
||||
}) : assert(activeRailColor != null),
|
||||
assert(inactiveRailColor != null),
|
||||
assert(disabledActiveRailColor != null),
|
||||
assert(disabledInactiveRailColor != null),
|
||||
assert(activeTickMarkColor != null),
|
||||
assert(inactiveTickMarkColor != null),
|
||||
assert(disabledActiveTickMarkColor != null),
|
||||
assert(disabledInactiveTickMarkColor != null),
|
||||
assert(thumbColor != null),
|
||||
assert(disabledThumbColor != null),
|
||||
assert(overlayColor != null),
|
||||
assert(valueIndicatorColor != null),
|
||||
assert(thumbShape != null),
|
||||
assert(valueIndicatorShape != null),
|
||||
assert(valueIndicatorTextStyle != null),
|
||||
assert(showValueIndicator != null);
|
||||
|
||||
/// Generates a SliderThemeData from three main colors.
|
||||
///
|
||||
@ -223,10 +225,12 @@ class SliderThemeData extends Diagnosticable {
|
||||
@required Color primaryColor,
|
||||
@required Color primaryColorDark,
|
||||
@required Color primaryColorLight,
|
||||
@required TextStyle valueIndicatorTextStyle,
|
||||
}) {
|
||||
assert(primaryColor != null);
|
||||
assert(primaryColorDark != null);
|
||||
assert(primaryColorLight != null);
|
||||
assert(valueIndicatorTextStyle != null);
|
||||
|
||||
// These are Material Design defaults, and are used to derive
|
||||
// component Colors (with opacity) from base colors.
|
||||
@ -264,6 +268,7 @@ class SliderThemeData extends Diagnosticable {
|
||||
valueIndicatorColor: primaryColor.withAlpha(valueIndicatorAlpha),
|
||||
thumbShape: const RoundSliderThumbShape(),
|
||||
valueIndicatorShape: const PaddleSliderValueIndicatorShape(),
|
||||
valueIndicatorTextStyle: valueIndicatorTextStyle,
|
||||
showValueIndicator: ShowValueIndicator.onlyForDiscrete,
|
||||
);
|
||||
}
|
||||
@ -337,6 +342,11 @@ class SliderThemeData extends Diagnosticable {
|
||||
/// when the thumb is being touched.
|
||||
final ShowValueIndicator showValueIndicator;
|
||||
|
||||
/// The text style for the text on the value indicator.
|
||||
///
|
||||
/// By default this is the [ThemeData.accentTextTheme.body2] text theme.
|
||||
final TextStyle valueIndicatorTextStyle;
|
||||
|
||||
/// Creates a copy of this object but with the given fields replaced with the
|
||||
/// new values.
|
||||
SliderThemeData copyWith({
|
||||
@ -355,6 +365,7 @@ class SliderThemeData extends Diagnosticable {
|
||||
SliderComponentShape thumbShape,
|
||||
SliderComponentShape valueIndicatorShape,
|
||||
ShowValueIndicator showValueIndicator,
|
||||
TextStyle valueIndicatorTextStyle,
|
||||
}) {
|
||||
return new SliderThemeData(
|
||||
activeRailColor: activeRailColor ?? this.activeRailColor,
|
||||
@ -372,6 +383,7 @@ class SliderThemeData extends Diagnosticable {
|
||||
thumbShape: thumbShape ?? this.thumbShape,
|
||||
valueIndicatorShape: valueIndicatorShape ?? this.valueIndicatorShape,
|
||||
showValueIndicator: showValueIndicator ?? this.showValueIndicator,
|
||||
valueIndicatorTextStyle: valueIndicatorTextStyle ?? this.valueIndicatorTextStyle,
|
||||
);
|
||||
}
|
||||
|
||||
@ -410,6 +422,7 @@ class SliderThemeData extends Diagnosticable {
|
||||
thumbShape: t < 0.5 ? a.thumbShape : b.thumbShape,
|
||||
valueIndicatorShape: t < 0.5 ? a.valueIndicatorShape : b.valueIndicatorShape,
|
||||
showValueIndicator: t < 0.5 ? a.showValueIndicator : b.showValueIndicator,
|
||||
valueIndicatorTextStyle: TextStyle.lerp(a.valueIndicatorTextStyle, b.valueIndicatorTextStyle, t),
|
||||
);
|
||||
}
|
||||
|
||||
@ -431,6 +444,7 @@ class SliderThemeData extends Diagnosticable {
|
||||
thumbShape,
|
||||
valueIndicatorShape,
|
||||
showValueIndicator,
|
||||
valueIndicatorTextStyle,
|
||||
);
|
||||
}
|
||||
|
||||
@ -457,7 +471,8 @@ class SliderThemeData extends Diagnosticable {
|
||||
otherData.valueIndicatorColor == valueIndicatorColor &&
|
||||
otherData.thumbShape == thumbShape &&
|
||||
otherData.valueIndicatorShape == valueIndicatorShape &&
|
||||
otherData.showValueIndicator == showValueIndicator;
|
||||
otherData.showValueIndicator == showValueIndicator &&
|
||||
otherData.valueIndicatorTextStyle == valueIndicatorTextStyle;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -468,6 +483,7 @@ class SliderThemeData extends Diagnosticable {
|
||||
primaryColor: defaultTheme.primaryColor,
|
||||
primaryColorDark: defaultTheme.primaryColorDark,
|
||||
primaryColorLight: defaultTheme.primaryColorLight,
|
||||
valueIndicatorTextStyle: defaultTheme.accentTextTheme.body2,
|
||||
);
|
||||
description.add(new DiagnosticsProperty<Color>('activeRailColor', activeRailColor, defaultValue: defaultData.activeRailColor));
|
||||
description.add(new DiagnosticsProperty<Color>('inactiveRailColor', inactiveRailColor, defaultValue: defaultData.inactiveRailColor));
|
||||
@ -484,6 +500,7 @@ class SliderThemeData extends Diagnosticable {
|
||||
description.add(new DiagnosticsProperty<SliderComponentShape>('thumbShape', thumbShape, defaultValue: defaultData.thumbShape, level: DiagnosticLevel.debug));
|
||||
description.add(new DiagnosticsProperty<SliderComponentShape>('valueIndicatorShape', valueIndicatorShape, defaultValue: defaultData.valueIndicatorShape, level: DiagnosticLevel.debug));
|
||||
description.add(new EnumProperty<ShowValueIndicator>('showValueIndicator', showValueIndicator, defaultValue: defaultData.showValueIndicator));
|
||||
description.add(new DiagnosticsProperty<TextStyle>('valueIndicatorTextStyle', valueIndicatorTextStyle, defaultValue: defaultData.valueIndicatorTextStyle));
|
||||
}
|
||||
}
|
||||
|
||||
@ -510,24 +527,27 @@ abstract class SliderComponentShape {
|
||||
/// [activationAnimation] is an animation triggered when the user beings
|
||||
/// to interact with the slider. It reverses when the user stops interacting
|
||||
/// with the slider.
|
||||
///
|
||||
/// [enableAnimation] is an animation triggered when the [Slider] is enabled,
|
||||
/// and it reverses when the slider is disabled.
|
||||
///
|
||||
/// [value] is the current parametric value (from 0.0 to 1.0) of the slider.
|
||||
///
|
||||
/// If [labelPainter] is non-null, then [labelPainter.paint] should be
|
||||
/// called with the location that the label should appear. If the labelPainter
|
||||
/// passed is null, then no label was supplied to the [Slider].
|
||||
/// [value] is the current parametric value (from 0.0 to 1.0) of the slider.
|
||||
void paint(
|
||||
RenderBox parentBox,
|
||||
PaintingContext context,
|
||||
bool isDiscrete,
|
||||
Offset thumbCenter,
|
||||
Offset thumbCenter, {
|
||||
Animation<double> activationAnimation,
|
||||
Animation<double> enableAnimation,
|
||||
bool isDiscrete,
|
||||
TextPainter labelPainter,
|
||||
RenderBox parentBox,
|
||||
SliderThemeData sliderTheme,
|
||||
TextDirection textDirection,
|
||||
double value,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// This is the default shape to a [Slider]'s thumb if no
|
||||
@ -552,17 +572,17 @@ class RoundSliderThumbShape extends SliderComponentShape {
|
||||
|
||||
@override
|
||||
void paint(
|
||||
RenderBox parentBox,
|
||||
PaintingContext context,
|
||||
bool isDiscrete,
|
||||
Offset thumbCenter,
|
||||
Offset thumbCenter, {
|
||||
Animation<double> activationAnimation,
|
||||
Animation<double> enableAnimation,
|
||||
bool isDiscrete,
|
||||
TextPainter labelPainter,
|
||||
RenderBox parentBox,
|
||||
SliderThemeData sliderTheme,
|
||||
TextDirection textDirection,
|
||||
double value,
|
||||
) {
|
||||
}) {
|
||||
final Canvas canvas = context.canvas;
|
||||
final Tween<double> radiusTween = new Tween<double>(
|
||||
begin: _disabledThumbRadius,
|
||||
@ -624,8 +644,7 @@ class PaddleSliderValueIndicatorShape extends SliderComponentShape {
|
||||
static const double _twoSeventyDegrees = 3.0 * math.pi / 2.0;
|
||||
static const double _ninetyDegrees = math.pi / 2.0;
|
||||
static const double _thirtyDegrees = math.pi / 6.0;
|
||||
static const Size _preferredSize =
|
||||
const Size.fromHeight(_distanceBetweenTopBottomCenters + _topLobeRadius + _bottomLobeRadius);
|
||||
static const Size _preferredSize = const Size.fromHeight(_distanceBetweenTopBottomCenters + _topLobeRadius + _bottomLobeRadius);
|
||||
// Set to true if you want a rectangle to be drawn around the label bubble.
|
||||
// This helps with building tests that check that the label draws in the right
|
||||
// place (because it prints the rect in the failed test output). It should not
|
||||
@ -767,9 +786,11 @@ class PaddleSliderValueIndicatorShape extends SliderComponentShape {
|
||||
double shift = _getIdealOffset(parentBox, halfWidthNeeded, overallScale, center);
|
||||
double leftWidthNeeded;
|
||||
double rightWidthNeeded;
|
||||
if (shift < 0.0) { // shifting to the left
|
||||
if (shift < 0.0) {
|
||||
// shifting to the left
|
||||
shift = math.max(shift, -halfWidthNeeded);
|
||||
} else { // shifting to the right
|
||||
} else {
|
||||
// shifting to the right
|
||||
shift = math.min(shift, halfWidthNeeded);
|
||||
}
|
||||
rightWidthNeeded = halfWidthNeeded + shift;
|
||||
@ -808,21 +829,23 @@ class PaddleSliderValueIndicatorShape extends SliderComponentShape {
|
||||
final double stretch = (neckStretchBaseline * t).clamp(0.0, 10.0 * neckStretchBaseline);
|
||||
final Offset neckStretch = new Offset(0.0, neckStretchBaseline - stretch);
|
||||
|
||||
assert(!_debuggingLabelLocation || () {
|
||||
final Offset leftCenter = _topLobeCenter - new Offset(leftWidthNeeded, 0.0) + neckStretch;
|
||||
final Offset rightCenter = _topLobeCenter + new Offset(rightWidthNeeded, 0.0) + neckStretch;
|
||||
final Rect valueRect = new Rect.fromLTRB(
|
||||
leftCenter.dx - _topLobeRadius,
|
||||
leftCenter.dy - _topLobeRadius,
|
||||
rightCenter.dx + _topLobeRadius,
|
||||
rightCenter.dy + _topLobeRadius,
|
||||
);
|
||||
final Paint outlinePaint = new Paint()
|
||||
..color = const Color(0xffff0000)
|
||||
..style = PaintingStyle.stroke..strokeWidth = 1.0;
|
||||
canvas.drawRect(valueRect, outlinePaint);
|
||||
return true;
|
||||
}());
|
||||
assert(!_debuggingLabelLocation ||
|
||||
() {
|
||||
final Offset leftCenter = _topLobeCenter - new Offset(leftWidthNeeded, 0.0) + neckStretch;
|
||||
final Offset rightCenter = _topLobeCenter + new Offset(rightWidthNeeded, 0.0) + neckStretch;
|
||||
final Rect valueRect = new Rect.fromLTRB(
|
||||
leftCenter.dx - _topLobeRadius,
|
||||
leftCenter.dy - _topLobeRadius,
|
||||
rightCenter.dx + _topLobeRadius,
|
||||
rightCenter.dy + _topLobeRadius,
|
||||
);
|
||||
final Paint outlinePaint = new Paint()
|
||||
..color = const Color(0xffff0000)
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 1.0;
|
||||
canvas.drawRect(valueRect, outlinePaint);
|
||||
return true;
|
||||
}());
|
||||
|
||||
_addArc(
|
||||
path,
|
||||
@ -865,18 +888,17 @@ class PaddleSliderValueIndicatorShape extends SliderComponentShape {
|
||||
|
||||
@override
|
||||
void paint(
|
||||
RenderBox parentBox,
|
||||
PaintingContext context,
|
||||
bool isDiscrete,
|
||||
Offset thumbCenter,
|
||||
Offset thumbCenter, {
|
||||
Animation<double> activationAnimation,
|
||||
Animation<double> enableAnimation,
|
||||
bool isDiscrete,
|
||||
TextPainter labelPainter,
|
||||
RenderBox parentBox,
|
||||
SliderThemeData sliderTheme,
|
||||
TextDirection textDirection,
|
||||
double value,
|
||||
) {
|
||||
assert(labelPainter != null);
|
||||
}) {
|
||||
final ColorTween enableColor = new ColorTween(
|
||||
begin: sliderTheme.disabledThumbColor,
|
||||
end: sliderTheme.valueIndicatorColor,
|
||||
|
@ -166,6 +166,7 @@ class ThemeData extends Diagnosticable {
|
||||
primaryColor: primaryColor,
|
||||
primaryColorLight: primaryColorLight,
|
||||
primaryColorDark: primaryColorDark,
|
||||
valueIndicatorTextStyle: accentTextTheme.body2,
|
||||
);
|
||||
return new ThemeData.raw(
|
||||
brightness: brightness,
|
||||
|
@ -25,17 +25,17 @@ class LoggingThumbShape extends SliderComponentShape {
|
||||
|
||||
@override
|
||||
void paint(
|
||||
RenderBox parentBox,
|
||||
PaintingContext context,
|
||||
bool isDiscrete,
|
||||
Offset thumbCenter,
|
||||
Offset thumbCenter, {
|
||||
Animation<double> activationAnimation,
|
||||
Animation<double> enableAnimation,
|
||||
bool isDiscrete,
|
||||
TextPainter labelPainter,
|
||||
RenderBox parentBox,
|
||||
SliderThemeData sliderTheme,
|
||||
TextDirection textDirection,
|
||||
double value,
|
||||
) {
|
||||
}) {
|
||||
log.add(thumbCenter);
|
||||
final Paint thumbPaint = new Paint()..color = Colors.red;
|
||||
context.canvas.drawCircle(thumbCenter, 5.0, thumbPaint);
|
||||
|
@ -104,11 +104,13 @@ void main() {
|
||||
const Color customColor1 = const Color(0xcafefeed);
|
||||
const Color customColor2 = const Color(0xdeadbeef);
|
||||
const Color customColor3 = const Color(0xdecaface);
|
||||
const Color customColor4 = const Color(0xfeedcafe);
|
||||
|
||||
final SliderThemeData sliderTheme = new SliderThemeData.fromPrimaryColors(
|
||||
primaryColor: customColor1,
|
||||
primaryColorDark: customColor2,
|
||||
primaryColorLight: customColor3,
|
||||
valueIndicatorTextStyle: new ThemeData.fallback().accentTextTheme.body2.copyWith(color: customColor4),
|
||||
);
|
||||
|
||||
expect(sliderTheme.activeRailColor, equals(customColor1.withAlpha(0xff)));
|
||||
@ -126,6 +128,7 @@ void main() {
|
||||
expect(sliderTheme.thumbShape, equals(const isInstanceOf<RoundSliderThumbShape>()));
|
||||
expect(sliderTheme.valueIndicatorShape, equals(const isInstanceOf<PaddleSliderValueIndicatorShape>()));
|
||||
expect(sliderTheme.showValueIndicator, equals(ShowValueIndicator.onlyForDiscrete));
|
||||
expect(sliderTheme.valueIndicatorTextStyle.color, equals(customColor4));
|
||||
});
|
||||
|
||||
testWidgets('SliderThemeData lerps correctly', (WidgetTester tester) async {
|
||||
@ -133,11 +136,13 @@ void main() {
|
||||
primaryColor: Colors.black,
|
||||
primaryColorDark: Colors.black,
|
||||
primaryColorLight: Colors.black,
|
||||
valueIndicatorTextStyle: new ThemeData.fallback().accentTextTheme.body2.copyWith(color: Colors.black),
|
||||
);
|
||||
final SliderThemeData sliderThemeWhite = new SliderThemeData.fromPrimaryColors(
|
||||
primaryColor: Colors.white,
|
||||
primaryColorDark: Colors.white,
|
||||
primaryColorLight: Colors.white,
|
||||
valueIndicatorTextStyle: new ThemeData.fallback().accentTextTheme.body2.copyWith(color: Colors.white),
|
||||
);
|
||||
final SliderThemeData lerp = SliderThemeData.lerp(sliderThemeBlack, sliderThemeWhite, 0.5);
|
||||
const Color middleGrey = const Color(0xff7f7f7f);
|
||||
@ -153,6 +158,7 @@ void main() {
|
||||
expect(lerp.disabledThumbColor, equals(middleGrey.withAlpha(0x52)));
|
||||
expect(lerp.overlayColor, equals(middleGrey.withAlpha(0x29)));
|
||||
expect(lerp.valueIndicatorColor, equals(middleGrey.withAlpha(0xff)));
|
||||
expect(lerp.valueIndicatorTextStyle.color, equals(middleGrey.withAlpha(0xff)));
|
||||
});
|
||||
|
||||
testWidgets('Default slider thumb shape draws correctly', (WidgetTester tester) async {
|
||||
|
Loading…
x
Reference in New Issue
Block a user