mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
parent
3437b77007
commit
7b549def56
@ -161,6 +161,7 @@ class _CupertinoSliderRenderObjectWidget extends LeafRenderObjectWidget {
|
|||||||
activeColor: activeColor,
|
activeColor: activeColor,
|
||||||
onChanged: onChanged,
|
onChanged: onChanged,
|
||||||
vsync: vsync,
|
vsync: vsync,
|
||||||
|
textDirection: Directionality.of(context),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +171,8 @@ class _CupertinoSliderRenderObjectWidget extends LeafRenderObjectWidget {
|
|||||||
..value = value
|
..value = value
|
||||||
..divisions = divisions
|
..divisions = divisions
|
||||||
..activeColor = activeColor
|
..activeColor = activeColor
|
||||||
..onChanged = onChanged;
|
..onChanged = onChanged
|
||||||
|
..textDirection = Directionality.of(context);
|
||||||
// Ticker provider cannot change since there's a 1:1 relationship between
|
// Ticker provider cannot change since there's a 1:1 relationship between
|
||||||
// the _SliderRenderObjectWidget object and the _SliderState object.
|
// the _SliderRenderObjectWidget object and the _SliderState object.
|
||||||
}
|
}
|
||||||
@ -192,11 +194,14 @@ class _RenderCupertinoSlider extends RenderConstrainedBox implements SemanticsAc
|
|||||||
Color activeColor,
|
Color activeColor,
|
||||||
ValueChanged<double> onChanged,
|
ValueChanged<double> onChanged,
|
||||||
TickerProvider vsync,
|
TickerProvider vsync,
|
||||||
|
@required TextDirection textDirection,
|
||||||
}) : assert(value != null && value >= 0.0 && value <= 1.0),
|
}) : assert(value != null && value >= 0.0 && value <= 1.0),
|
||||||
|
assert(textDirection != null),
|
||||||
_value = value,
|
_value = value,
|
||||||
_divisions = divisions,
|
_divisions = divisions,
|
||||||
_activeColor = activeColor,
|
_activeColor = activeColor,
|
||||||
_onChanged = onChanged,
|
_onChanged = onChanged,
|
||||||
|
_textDirection = textDirection,
|
||||||
super(additionalConstraints: const BoxConstraints.tightFor(width: _kSliderWidth, height: _kSliderHeight)) {
|
super(additionalConstraints: const BoxConstraints.tightFor(width: _kSliderWidth, height: _kSliderHeight)) {
|
||||||
_drag = new HorizontalDragGestureRecognizer()
|
_drag = new HorizontalDragGestureRecognizer()
|
||||||
..onStart = _handleDragStart
|
..onStart = _handleDragStart
|
||||||
@ -251,6 +256,16 @@ class _RenderCupertinoSlider extends RenderConstrainedBox implements SemanticsAc
|
|||||||
markNeedsSemanticsUpdate(noGeometry: true);
|
markNeedsSemanticsUpdate(noGeometry: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextDirection get textDirection => _textDirection;
|
||||||
|
TextDirection _textDirection;
|
||||||
|
set textDirection(TextDirection value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_textDirection == value)
|
||||||
|
return;
|
||||||
|
_textDirection = value;
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
AnimationController _position;
|
AnimationController _position;
|
||||||
|
|
||||||
HorizontalDragGestureRecognizer _drag;
|
HorizontalDragGestureRecognizer _drag;
|
||||||
@ -265,7 +280,18 @@ class _RenderCupertinoSlider extends RenderConstrainedBox implements SemanticsAc
|
|||||||
|
|
||||||
double get _trackLeft => _kPadding;
|
double get _trackLeft => _kPadding;
|
||||||
double get _trackRight => size.width - _kPadding;
|
double get _trackRight => size.width - _kPadding;
|
||||||
double get _thumbCenter => lerpDouble(_trackLeft + CupertinoThumbPainter.radius, _trackRight - CupertinoThumbPainter.radius, _value);
|
double get _thumbCenter {
|
||||||
|
double visualPosition;
|
||||||
|
switch (textDirection) {
|
||||||
|
case TextDirection.rtl:
|
||||||
|
visualPosition = 1.0 - _value;
|
||||||
|
break;
|
||||||
|
case TextDirection.ltr:
|
||||||
|
visualPosition = _value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return lerpDouble(_trackLeft + CupertinoThumbPainter.radius, _trackRight - CupertinoThumbPainter.radius, visualPosition);
|
||||||
|
}
|
||||||
|
|
||||||
bool get isInteractive => onChanged != null;
|
bool get isInteractive => onChanged != null;
|
||||||
|
|
||||||
@ -279,7 +305,15 @@ class _RenderCupertinoSlider extends RenderConstrainedBox implements SemanticsAc
|
|||||||
void _handleDragUpdate(DragUpdateDetails details) {
|
void _handleDragUpdate(DragUpdateDetails details) {
|
||||||
if (isInteractive) {
|
if (isInteractive) {
|
||||||
final double extent = math.max(_kPadding, size.width - 2.0 * (_kPadding + CupertinoThumbPainter.radius));
|
final double extent = math.max(_kPadding, size.width - 2.0 * (_kPadding + CupertinoThumbPainter.radius));
|
||||||
_currentDragValue += details.primaryDelta / extent;
|
final double valueDelta = details.primaryDelta / extent;
|
||||||
|
switch (textDirection) {
|
||||||
|
case TextDirection.rtl:
|
||||||
|
_currentDragValue -= valueDelta;
|
||||||
|
break;
|
||||||
|
case TextDirection.ltr:
|
||||||
|
_currentDragValue += valueDelta;
|
||||||
|
break;
|
||||||
|
}
|
||||||
onChanged(_discretizedCurrentDragValue);
|
onChanged(_discretizedCurrentDragValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -304,9 +338,21 @@ class _RenderCupertinoSlider extends RenderConstrainedBox implements SemanticsAc
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void paint(PaintingContext context, Offset offset) {
|
void paint(PaintingContext context, Offset offset) {
|
||||||
final Canvas canvas = context.canvas;
|
double visualPosition;
|
||||||
|
Color leftColor;
|
||||||
final double value = _position.value;
|
Color rightColor;
|
||||||
|
switch (textDirection) {
|
||||||
|
case TextDirection.rtl:
|
||||||
|
visualPosition = 1.0 - _position.value;
|
||||||
|
leftColor = _kTrackColor;
|
||||||
|
rightColor = _activeColor;
|
||||||
|
break;
|
||||||
|
case TextDirection.ltr:
|
||||||
|
visualPosition = _position.value;
|
||||||
|
leftColor = _activeColor;
|
||||||
|
rightColor = _kTrackColor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
final double trackCenter = offset.dy + size.height / 2.0;
|
final double trackCenter = offset.dy + size.height / 2.0;
|
||||||
final double trackLeft = offset.dx + _trackLeft;
|
final double trackLeft = offset.dx + _trackLeft;
|
||||||
@ -315,15 +361,16 @@ class _RenderCupertinoSlider extends RenderConstrainedBox implements SemanticsAc
|
|||||||
final double trackRight = offset.dx + _trackRight;
|
final double trackRight = offset.dx + _trackRight;
|
||||||
final double trackActive = offset.dx + _thumbCenter;
|
final double trackActive = offset.dx + _thumbCenter;
|
||||||
|
|
||||||
|
final Canvas canvas = context.canvas;
|
||||||
final Paint paint = new Paint();
|
final Paint paint = new Paint();
|
||||||
|
|
||||||
if (value > 0.0) {
|
if (visualPosition > 0.0) {
|
||||||
paint.color = _activeColor;
|
paint.color = rightColor;
|
||||||
canvas.drawRRect(new RRect.fromLTRBXY(trackLeft, trackTop, trackActive, trackBottom, 1.0, 1.0), paint);
|
canvas.drawRRect(new RRect.fromLTRBXY(trackLeft, trackTop, trackActive, trackBottom, 1.0, 1.0), paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value < 1.0) {
|
if (visualPosition < 1.0) {
|
||||||
paint.color = _kTrackColor;
|
paint.color = leftColor;
|
||||||
canvas.drawRRect(new RRect.fromLTRBXY(trackActive, trackTop, trackRight, trackBottom, 1.0, 1.0), paint);
|
canvas.drawRRect(new RRect.fromLTRBXY(trackActive, trackTop, trackRight, trackBottom, 1.0, 1.0), paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,6 +229,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
|
|||||||
textTheme: textTheme,
|
textTheme: textTheme,
|
||||||
onChanged: onChanged,
|
onChanged: onChanged,
|
||||||
vsync: vsync,
|
vsync: vsync,
|
||||||
|
textDirection: Directionality.of(context),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +243,8 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
|
|||||||
..inactiveColor = inactiveColor
|
..inactiveColor = inactiveColor
|
||||||
..thumbOpenAtMin = thumbOpenAtMin
|
..thumbOpenAtMin = thumbOpenAtMin
|
||||||
..textTheme = textTheme
|
..textTheme = textTheme
|
||||||
..onChanged = onChanged;
|
..onChanged = onChanged
|
||||||
|
..textDirection = Directionality.of(context);
|
||||||
// Ticker provider cannot change since there's a 1:1 relationship between
|
// Ticker provider cannot change since there's a 1:1 relationship between
|
||||||
// the _SliderRenderObjectWidget object and the _SliderState object.
|
// the _SliderRenderObjectWidget object and the _SliderState object.
|
||||||
}
|
}
|
||||||
@ -290,14 +292,17 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
|||||||
TextTheme textTheme,
|
TextTheme textTheme,
|
||||||
ValueChanged<double> onChanged,
|
ValueChanged<double> onChanged,
|
||||||
TickerProvider vsync,
|
TickerProvider vsync,
|
||||||
|
@required TextDirection textDirection,
|
||||||
}) : assert(value != null && value >= 0.0 && value <= 1.0),
|
}) : assert(value != null && value >= 0.0 && value <= 1.0),
|
||||||
|
assert(textDirection != null),
|
||||||
_value = value,
|
_value = value,
|
||||||
_divisions = divisions,
|
_divisions = divisions,
|
||||||
_activeColor = activeColor,
|
_activeColor = activeColor,
|
||||||
_inactiveColor = inactiveColor,
|
_inactiveColor = inactiveColor,
|
||||||
_thumbOpenAtMin = thumbOpenAtMin,
|
_thumbOpenAtMin = thumbOpenAtMin,
|
||||||
_textTheme = textTheme,
|
_textTheme = textTheme,
|
||||||
_onChanged = onChanged {
|
_onChanged = onChanged,
|
||||||
|
_textDirection = textDirection {
|
||||||
this.label = label;
|
this.label = label;
|
||||||
final GestureArenaTeam team = new GestureArenaTeam();
|
final GestureArenaTeam team = new GestureArenaTeam();
|
||||||
_drag = new HorizontalDragGestureRecognizer()
|
_drag = new HorizontalDragGestureRecognizer()
|
||||||
@ -415,6 +420,17 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextDirection get textDirection => _textDirection;
|
||||||
|
TextDirection _textDirection;
|
||||||
|
set textDirection(TextDirection value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_textDirection == value)
|
||||||
|
return;
|
||||||
|
_textDirection = value;
|
||||||
|
// TODO(abarth): Update _labelPainter's text direction.
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
double get _trackLength => size.width - 2.0 * _kReactionRadius;
|
double get _trackLength => size.width - 2.0 * _kReactionRadius;
|
||||||
|
|
||||||
Animation<double> _reaction;
|
Animation<double> _reaction;
|
||||||
@ -430,8 +446,19 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
|||||||
|
|
||||||
bool get isInteractive => onChanged != null;
|
bool get isInteractive => onChanged != null;
|
||||||
|
|
||||||
|
double _getValueFromVisualPosition(double visualPosition) {
|
||||||
|
switch (textDirection) {
|
||||||
|
case TextDirection.rtl:
|
||||||
|
return 1.0 - visualPosition;
|
||||||
|
case TextDirection.ltr:
|
||||||
|
return visualPosition;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
double _getValueFromGlobalPosition(Offset globalPosition) {
|
double _getValueFromGlobalPosition(Offset globalPosition) {
|
||||||
return (globalToLocal(globalPosition).dx - _kReactionRadius) / _trackLength;
|
final double visualPosition = (globalToLocal(globalPosition).dx - _kReactionRadius) / _trackLength;
|
||||||
|
return _getValueFromVisualPosition(visualPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
double _discretize(double value) {
|
double _discretize(double value) {
|
||||||
@ -452,7 +479,15 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
|||||||
|
|
||||||
void _handleDragUpdate(DragUpdateDetails details) {
|
void _handleDragUpdate(DragUpdateDetails details) {
|
||||||
if (isInteractive) {
|
if (isInteractive) {
|
||||||
_currentDragValue += details.primaryDelta / _trackLength;
|
final double valueDelta = details.primaryDelta / _trackLength;
|
||||||
|
switch (textDirection) {
|
||||||
|
case TextDirection.rtl:
|
||||||
|
_currentDragValue -= valueDelta;
|
||||||
|
break;
|
||||||
|
case TextDirection.ltr:
|
||||||
|
_currentDragValue += valueDelta;
|
||||||
|
break;
|
||||||
|
}
|
||||||
onChanged(_discretize(_currentDragValue));
|
onChanged(_discretize(_currentDragValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -523,6 +558,26 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
|||||||
final double trackLength = size.width - 2 * _kReactionRadius;
|
final double trackLength = size.width - 2 * _kReactionRadius;
|
||||||
final bool enabled = isInteractive;
|
final bool enabled = isInteractive;
|
||||||
final double value = _position.value;
|
final double value = _position.value;
|
||||||
|
final bool thumbAtMin = value == 0.0;
|
||||||
|
|
||||||
|
final Paint primaryPaint = new Paint()..color = enabled ? _activeColor : _inactiveColor;
|
||||||
|
final Paint trackPaint = new Paint()..color = _inactiveColor;
|
||||||
|
|
||||||
|
double visualPosition;
|
||||||
|
Paint leftPaint;
|
||||||
|
Paint rightPaint;
|
||||||
|
switch (textDirection) {
|
||||||
|
case TextDirection.rtl:
|
||||||
|
visualPosition = 1.0 - value;
|
||||||
|
leftPaint = trackPaint;
|
||||||
|
rightPaint = primaryPaint;
|
||||||
|
break;
|
||||||
|
case TextDirection.ltr:
|
||||||
|
visualPosition = value;
|
||||||
|
leftPaint = primaryPaint;
|
||||||
|
rightPaint = trackPaint;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
final double additionalHeightForLabel = _getAdditionalHeightForLabel(label);
|
final double additionalHeightForLabel = _getAdditionalHeightForLabel(label);
|
||||||
final double trackCenter = offset.dy + (size.height - additionalHeightForLabel) / 2.0 + additionalHeightForLabel;
|
final double trackCenter = offset.dy + (size.height - additionalHeightForLabel) / 2.0 + additionalHeightForLabel;
|
||||||
@ -530,26 +585,23 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
|||||||
final double trackTop = trackCenter - 1.0;
|
final double trackTop = trackCenter - 1.0;
|
||||||
final double trackBottom = trackCenter + 1.0;
|
final double trackBottom = trackCenter + 1.0;
|
||||||
final double trackRight = trackLeft + trackLength;
|
final double trackRight = trackLeft + trackLength;
|
||||||
final double trackActive = trackLeft + trackLength * value;
|
final double trackActive = trackLeft + trackLength * visualPosition;
|
||||||
|
|
||||||
final Paint primaryPaint = new Paint()..color = enabled ? _activeColor : _inactiveColor;
|
|
||||||
final Paint trackPaint = new Paint()..color = _inactiveColor;
|
|
||||||
|
|
||||||
final Offset thumbCenter = new Offset(trackActive, trackCenter);
|
final Offset thumbCenter = new Offset(trackActive, trackCenter);
|
||||||
final double thumbRadius = enabled ? _kThumbRadiusTween.evaluate(_reaction) : _kDisabledThumbRadius;
|
final double thumbRadius = enabled ? _kThumbRadiusTween.evaluate(_reaction) : _kDisabledThumbRadius;
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (value > 0.0)
|
if (visualPosition > 0.0)
|
||||||
canvas.drawRect(new Rect.fromLTRB(trackLeft, trackTop, trackActive, trackBottom), primaryPaint);
|
canvas.drawRect(new Rect.fromLTRB(trackLeft, trackTop, trackActive, trackBottom), leftPaint);
|
||||||
if (value < 1.0) {
|
if (visualPosition < 1.0) {
|
||||||
final bool hasBalloon = _reaction.status != AnimationStatus.dismissed && label != null;
|
final bool hasBalloon = _reaction.status != AnimationStatus.dismissed && label != null;
|
||||||
final double trackActiveDelta = hasBalloon ? 0.0 : thumbRadius - 1.0;
|
final double trackActiveDelta = hasBalloon ? 0.0 : thumbRadius - 1.0;
|
||||||
canvas.drawRect(new Rect.fromLTRB(trackActive + trackActiveDelta, trackTop, trackRight, trackBottom), trackPaint);
|
canvas.drawRect(new Rect.fromLTRB(trackActive + trackActiveDelta, trackTop, trackRight, trackBottom), rightPaint);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (value > 0.0)
|
if (visualPosition > 0.0)
|
||||||
canvas.drawRect(new Rect.fromLTRB(trackLeft, trackTop, trackActive - _kDisabledThumbRadius - 2, trackBottom), trackPaint);
|
canvas.drawRect(new Rect.fromLTRB(trackLeft, trackTop, trackActive - _kDisabledThumbRadius - 2, trackBottom), trackPaint);
|
||||||
if (value < 1.0)
|
if (visualPosition < 1.0)
|
||||||
canvas.drawRect(new Rect.fromLTRB(trackActive + _kDisabledThumbRadius + 2, trackTop, trackRight, trackBottom), trackPaint);
|
canvas.drawRect(new Rect.fromLTRB(trackActive + _kDisabledThumbRadius + 2, trackTop, trackRight, trackBottom), trackPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,7 +641,7 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
|||||||
_labelPainter.paint(canvas, labelOffset);
|
_labelPainter.paint(canvas, labelOffset);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
final Color reactionBaseColor = value == 0.0 ? _kActiveTrackColor : _activeColor;
|
final Color reactionBaseColor = thumbAtMin ? _kActiveTrackColor : _activeColor;
|
||||||
final Paint reactionPaint = new Paint()..color = reactionBaseColor.withAlpha(kRadialReactionAlpha);
|
final Paint reactionPaint = new Paint()..color = reactionBaseColor.withAlpha(kRadialReactionAlpha);
|
||||||
canvas.drawCircle(thumbCenter, _kReactionRadiusTween.evaluate(_reaction), reactionPaint);
|
canvas.drawCircle(thumbCenter, _kReactionRadiusTween.evaluate(_reaction), reactionPaint);
|
||||||
}
|
}
|
||||||
@ -597,7 +649,7 @@ class _RenderSlider extends RenderBox implements SemanticsActionHandler {
|
|||||||
|
|
||||||
Paint thumbPaint = primaryPaint;
|
Paint thumbPaint = primaryPaint;
|
||||||
double thumbRadiusDelta = 0.0;
|
double thumbRadiusDelta = 0.0;
|
||||||
if (value == 0.0 && thumbOpenAtMin) {
|
if (thumbAtMin && thumbOpenAtMin) {
|
||||||
thumbPaint = trackPaint;
|
thumbPaint = trackPaint;
|
||||||
// This is destructive to trackPaint.
|
// This is destructive to trackPaint.
|
||||||
thumbPaint
|
thumbPaint
|
||||||
|
@ -11,12 +11,13 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
import '../widgets/semantics_tester.dart';
|
import '../widgets/semantics_tester.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Slider does not move when tapped', (WidgetTester tester) async {
|
testWidgets('Slider does not move when tapped (LTR)', (WidgetTester tester) async {
|
||||||
final Key sliderKey = new UniqueKey();
|
final Key sliderKey = new UniqueKey();
|
||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(new Directionality(
|
||||||
new StatefulBuilder(
|
textDirection: TextDirection.ltr,
|
||||||
|
child: new StatefulBuilder(
|
||||||
builder: (BuildContext context, StateSetter setState) {
|
builder: (BuildContext context, StateSetter setState) {
|
||||||
return new Material(
|
return new Material(
|
||||||
child: new Center(
|
child: new Center(
|
||||||
@ -33,7 +34,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
));
|
||||||
|
|
||||||
expect(value, equals(0.0));
|
expect(value, equals(0.0));
|
||||||
await tester.tap(find.byKey(sliderKey));
|
await tester.tap(find.byKey(sliderKey));
|
||||||
@ -44,12 +45,13 @@ void main() {
|
|||||||
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
|
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Slider moves when dragged', (WidgetTester tester) async {
|
testWidgets('Slider does not move when tapped (RTL)', (WidgetTester tester) async {
|
||||||
final Key sliderKey = new UniqueKey();
|
final Key sliderKey = new UniqueKey();
|
||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(new Directionality(
|
||||||
new StatefulBuilder(
|
textDirection: TextDirection.rtl,
|
||||||
|
child: new StatefulBuilder(
|
||||||
builder: (BuildContext context, StateSetter setState) {
|
builder: (BuildContext context, StateSetter setState) {
|
||||||
return new Material(
|
return new Material(
|
||||||
child: new Center(
|
child: new Center(
|
||||||
@ -66,7 +68,42 @@ void main() {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
));
|
||||||
|
|
||||||
|
expect(value, equals(0.0));
|
||||||
|
await tester.tap(find.byKey(sliderKey));
|
||||||
|
expect(value, equals(0.0));
|
||||||
|
await tester.pump(); // No animation should start.
|
||||||
|
// Check the transientCallbackCount before tearing down the widget to ensure
|
||||||
|
// that no animation is running.
|
||||||
|
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
testWidgets('Slider moves when dragged (LTR)', (WidgetTester tester) async {
|
||||||
|
final Key sliderKey = new UniqueKey();
|
||||||
|
double value = 0.0;
|
||||||
|
|
||||||
|
await tester.pumpWidget(new Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: new StatefulBuilder(
|
||||||
|
builder: (BuildContext context, StateSetter setState) {
|
||||||
|
return new Material(
|
||||||
|
child: new Center(
|
||||||
|
child: new CupertinoSlider(
|
||||||
|
key: sliderKey,
|
||||||
|
value: value,
|
||||||
|
onChanged: (double newValue) {
|
||||||
|
setState(() {
|
||||||
|
value = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
expect(value, equals(0.0));
|
expect(value, equals(0.0));
|
||||||
final Offset topLeft = tester.getTopLeft(find.byKey(sliderKey));
|
final Offset topLeft = tester.getTopLeft(find.byKey(sliderKey));
|
||||||
@ -81,15 +118,54 @@ void main() {
|
|||||||
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
|
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Slider moves when dragged (RTL)', (WidgetTester tester) async {
|
||||||
|
final Key sliderKey = new UniqueKey();
|
||||||
|
double value = 0.0;
|
||||||
|
|
||||||
|
await tester.pumpWidget(new Directionality(
|
||||||
|
textDirection: TextDirection.rtl,
|
||||||
|
child: new StatefulBuilder(
|
||||||
|
builder: (BuildContext context, StateSetter setState) {
|
||||||
|
return new Material(
|
||||||
|
child: new Center(
|
||||||
|
child: new CupertinoSlider(
|
||||||
|
key: sliderKey,
|
||||||
|
value: value,
|
||||||
|
onChanged: (double newValue) {
|
||||||
|
setState(() {
|
||||||
|
value = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(value, equals(0.0));
|
||||||
|
final Offset bottomRight = tester.getBottomRight(find.byKey(sliderKey));
|
||||||
|
const double unit = CupertinoThumbPainter.radius;
|
||||||
|
const double delta = 3.0 * unit;
|
||||||
|
await tester.dragFrom(bottomRight - const Offset(unit, unit), const Offset(-delta, 0.0));
|
||||||
|
final Size size = tester.getSize(find.byKey(sliderKey));
|
||||||
|
expect(value, equals(delta / (size.width - 2.0 * (8.0 + CupertinoThumbPainter.radius))));
|
||||||
|
await tester.pump(); // No animation should start.
|
||||||
|
// Check the transientCallbackCount before tearing down the widget to ensure
|
||||||
|
// that no animation is running.
|
||||||
|
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Slider Semantics', (WidgetTester tester) async {
|
testWidgets('Slider Semantics', (WidgetTester tester) async {
|
||||||
final SemanticsTester semantics = new SemanticsTester(tester);
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(new Directionality(
|
||||||
new CupertinoSlider(
|
textDirection: TextDirection.ltr,
|
||||||
|
child: new CupertinoSlider(
|
||||||
value: 0.5,
|
value: 0.5,
|
||||||
onChanged: (double v) {},
|
onChanged: (double v) {},
|
||||||
),
|
),
|
||||||
);
|
));
|
||||||
|
|
||||||
expect(semantics, hasSemantics(
|
expect(semantics, hasSemantics(
|
||||||
new TestSemantics.root(
|
new TestSemantics.root(
|
||||||
@ -105,12 +181,13 @@ void main() {
|
|||||||
));
|
));
|
||||||
|
|
||||||
// Disable slider
|
// Disable slider
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(new Directionality(
|
||||||
new CupertinoSlider(
|
textDirection: TextDirection.ltr,
|
||||||
|
child: new CupertinoSlider(
|
||||||
value: 0.5,
|
value: 0.5,
|
||||||
onChanged: null,
|
onChanged: null,
|
||||||
),
|
),
|
||||||
);
|
));
|
||||||
|
|
||||||
expect(semantics, hasSemantics(
|
expect(semantics, hasSemantics(
|
||||||
new TestSemantics.root(),
|
new TestSemantics.root(),
|
||||||
|
@ -13,27 +13,30 @@ import '../rendering/mock_canvas.dart';
|
|||||||
import '../widgets/semantics_tester.dart';
|
import '../widgets/semantics_tester.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Slider can move when tapped', (WidgetTester tester) async {
|
testWidgets('Slider can move when tapped (LTR)', (WidgetTester tester) async {
|
||||||
final Key sliderKey = new UniqueKey();
|
final Key sliderKey = new UniqueKey();
|
||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
new StatefulBuilder(
|
new Directionality(
|
||||||
builder: (BuildContext context, StateSetter setState) {
|
textDirection: TextDirection.ltr,
|
||||||
return new Material(
|
child: new StatefulBuilder(
|
||||||
child: new Center(
|
builder: (BuildContext context, StateSetter setState) {
|
||||||
child: new Slider(
|
return new Material(
|
||||||
key: sliderKey,
|
child: new Center(
|
||||||
value: value,
|
child: new Slider(
|
||||||
onChanged: (double newValue) {
|
key: sliderKey,
|
||||||
setState(() {
|
value: value,
|
||||||
value = newValue;
|
onChanged: (double newValue) {
|
||||||
});
|
setState(() {
|
||||||
},
|
value = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -42,6 +45,58 @@ void main() {
|
|||||||
expect(value, equals(0.5));
|
expect(value, equals(0.5));
|
||||||
await tester.pump(); // No animation should start.
|
await tester.pump(); // No animation should start.
|
||||||
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
|
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
|
||||||
|
|
||||||
|
final Offset topLeft = tester.getTopLeft(find.byKey(sliderKey));
|
||||||
|
final Offset bottomRight = tester.getBottomRight(find.byKey(sliderKey));
|
||||||
|
|
||||||
|
final Offset target = topLeft + (bottomRight - topLeft) / 4.0;
|
||||||
|
await tester.tapAt(target);
|
||||||
|
expect(value, closeTo(0.25, 0.05));
|
||||||
|
await tester.pump(); // No animation should start.
|
||||||
|
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Slider can move when tapped (RTL)', (WidgetTester tester) async {
|
||||||
|
final Key sliderKey = new UniqueKey();
|
||||||
|
double value = 0.0;
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
new Directionality(
|
||||||
|
textDirection: TextDirection.rtl,
|
||||||
|
child: new StatefulBuilder(
|
||||||
|
builder: (BuildContext context, StateSetter setState) {
|
||||||
|
return new Material(
|
||||||
|
child: new Center(
|
||||||
|
child: new Slider(
|
||||||
|
key: sliderKey,
|
||||||
|
value: value,
|
||||||
|
onChanged: (double newValue) {
|
||||||
|
setState(() {
|
||||||
|
value = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(value, equals(0.0));
|
||||||
|
await tester.tap(find.byKey(sliderKey));
|
||||||
|
expect(value, equals(0.5));
|
||||||
|
await tester.pump(); // No animation should start.
|
||||||
|
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
|
||||||
|
|
||||||
|
final Offset topLeft = tester.getTopLeft(find.byKey(sliderKey));
|
||||||
|
final Offset bottomRight = tester.getBottomRight(find.byKey(sliderKey));
|
||||||
|
|
||||||
|
final Offset target = topLeft + (bottomRight - topLeft) / 4.0;
|
||||||
|
await tester.tapAt(target);
|
||||||
|
expect(value, closeTo(0.75, 0.05));
|
||||||
|
await tester.pump(); // No animation should start.
|
||||||
|
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Slider take on discrete values', (WidgetTester tester) async {
|
testWidgets('Slider take on discrete values', (WidgetTester tester) async {
|
||||||
@ -49,28 +104,31 @@ void main() {
|
|||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
new StatefulBuilder(
|
new Directionality(
|
||||||
builder: (BuildContext context, StateSetter setState) {
|
textDirection: TextDirection.ltr,
|
||||||
return new Material(
|
child: new StatefulBuilder(
|
||||||
child: new Center(
|
builder: (BuildContext context, StateSetter setState) {
|
||||||
child: new SizedBox(
|
return new Material(
|
||||||
width: 144.0 + 2 * 16.0, // _kPreferredTotalWidth
|
child: new Center(
|
||||||
child: new Slider(
|
child: new SizedBox(
|
||||||
key: sliderKey,
|
width: 144.0 + 2 * 16.0, // _kPreferredTotalWidth
|
||||||
min: 0.0,
|
child: new Slider(
|
||||||
max: 100.0,
|
key: sliderKey,
|
||||||
divisions: 10,
|
min: 0.0,
|
||||||
value: value,
|
max: 100.0,
|
||||||
onChanged: (double newValue) {
|
divisions: 10,
|
||||||
setState(() {
|
value: value,
|
||||||
value = newValue;
|
onChanged: (double newValue) {
|
||||||
});
|
setState(() {
|
||||||
},
|
value = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -95,12 +153,15 @@ void main() {
|
|||||||
testWidgets('Slider can be given zero values',
|
testWidgets('Slider can be given zero values',
|
||||||
(WidgetTester tester) async {
|
(WidgetTester tester) async {
|
||||||
final List<double> log = <double>[];
|
final List<double> log = <double>[];
|
||||||
await tester.pumpWidget(new Material(
|
await tester.pumpWidget(new Directionality(
|
||||||
child: new Slider(
|
textDirection: TextDirection.ltr,
|
||||||
value: 0.0,
|
child: new Material(
|
||||||
min: 0.0,
|
child: new Slider(
|
||||||
max: 1.0,
|
value: 0.0,
|
||||||
onChanged: (double newValue) { log.add(newValue); },
|
min: 0.0,
|
||||||
|
max: 1.0,
|
||||||
|
onChanged: (double newValue) { log.add(newValue); },
|
||||||
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -108,12 +169,15 @@ void main() {
|
|||||||
expect(log, <double>[0.5]);
|
expect(log, <double>[0.5]);
|
||||||
log.clear();
|
log.clear();
|
||||||
|
|
||||||
await tester.pumpWidget(new Material(
|
await tester.pumpWidget(new Directionality(
|
||||||
child: new Slider(
|
textDirection: TextDirection.ltr,
|
||||||
value: 0.0,
|
child: new Material(
|
||||||
min: 0.0,
|
child: new Slider(
|
||||||
max: 0.0,
|
value: 0.0,
|
||||||
onChanged: (double newValue) { log.add(newValue); },
|
min: 0.0,
|
||||||
|
max: 0.0,
|
||||||
|
onChanged: (double newValue) { log.add(newValue); },
|
||||||
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -127,14 +191,17 @@ void main() {
|
|||||||
final Color customColor = const Color(0xFF4CD964);
|
final Color customColor = const Color(0xFF4CD964);
|
||||||
final ThemeData theme = new ThemeData(platform: TargetPlatform.android);
|
final ThemeData theme = new ThemeData(platform: TargetPlatform.android);
|
||||||
Widget buildApp(Color activeColor) {
|
Widget buildApp(Color activeColor) {
|
||||||
return new Material(
|
return new Directionality(
|
||||||
child: new Center(
|
textDirection: TextDirection.ltr,
|
||||||
child: new Theme(
|
child: new Material(
|
||||||
data: theme,
|
child: new Center(
|
||||||
child: new Slider(
|
child: new Theme(
|
||||||
value: 0.5,
|
data: theme,
|
||||||
activeColor: activeColor,
|
child: new Slider(
|
||||||
onChanged: (double newValue) {},
|
value: 0.5,
|
||||||
|
activeColor: activeColor,
|
||||||
|
onChanged: (double newValue) {},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -162,14 +229,17 @@ void main() {
|
|||||||
final Color customColor = const Color(0xFF4CD964);
|
final Color customColor = const Color(0xFF4CD964);
|
||||||
final ThemeData theme = new ThemeData(platform: TargetPlatform.android);
|
final ThemeData theme = new ThemeData(platform: TargetPlatform.android);
|
||||||
Widget buildApp(Color inactiveColor) {
|
Widget buildApp(Color inactiveColor) {
|
||||||
return new Material(
|
return new Directionality(
|
||||||
child: new Center(
|
textDirection: TextDirection.ltr,
|
||||||
child: new Theme(
|
child: new Material(
|
||||||
data: theme,
|
child: new Center(
|
||||||
child: new Slider(
|
child: new Theme(
|
||||||
value: 0.5,
|
data: theme,
|
||||||
inactiveColor: inactiveColor,
|
child: new Slider(
|
||||||
onChanged: (double newValue) {},
|
value: 0.5,
|
||||||
|
inactiveColor: inactiveColor,
|
||||||
|
onChanged: (double newValue) {},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -188,15 +258,47 @@ void main() {
|
|||||||
expect(sliderBox, paints..circle(color: theme.accentColor));
|
expect(sliderBox, paints..circle(color: theme.accentColor));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Slider can draw an open thumb at min',
|
testWidgets('Slider can draw an open thumb at min (LTR)',
|
||||||
(WidgetTester tester) async {
|
(WidgetTester tester) async {
|
||||||
Widget buildApp(bool thumbOpenAtMin) {
|
Widget buildApp(bool thumbOpenAtMin) {
|
||||||
return new Material(
|
return new Directionality(
|
||||||
child: new Center(
|
textDirection: TextDirection.ltr,
|
||||||
child: new Slider(
|
child: new Material(
|
||||||
value: 0.0,
|
child: new Center(
|
||||||
thumbOpenAtMin: thumbOpenAtMin,
|
child: new Slider(
|
||||||
onChanged: (double newValue) {},
|
value: 0.0,
|
||||||
|
thumbOpenAtMin: thumbOpenAtMin,
|
||||||
|
onChanged: (double newValue) {},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildApp(false));
|
||||||
|
|
||||||
|
final RenderBox sliderBox =
|
||||||
|
tester.firstRenderObject<RenderBox>(find.byType(Slider));
|
||||||
|
|
||||||
|
expect(sliderBox, paints..circle(style: PaintingStyle.fill));
|
||||||
|
expect(sliderBox, isNot(paints..circle()..circle()));
|
||||||
|
await tester.pumpWidget(buildApp(true));
|
||||||
|
expect(sliderBox, paints..circle(style: PaintingStyle.stroke));
|
||||||
|
expect(sliderBox, isNot(paints..circle()..circle()));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Slider can draw an open thumb at min (RTL)',
|
||||||
|
(WidgetTester tester) async {
|
||||||
|
Widget buildApp(bool thumbOpenAtMin) {
|
||||||
|
return new Directionality(
|
||||||
|
textDirection: TextDirection.rtl,
|
||||||
|
child: new Material(
|
||||||
|
child: new Center(
|
||||||
|
child: new Slider(
|
||||||
|
value: 0.0,
|
||||||
|
thumbOpenAtMin: thumbOpenAtMin,
|
||||||
|
onChanged: (double newValue) {},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -217,19 +319,22 @@ void main() {
|
|||||||
testWidgets('Slider can tap in vertical scroller',
|
testWidgets('Slider can tap in vertical scroller',
|
||||||
(WidgetTester tester) async {
|
(WidgetTester tester) async {
|
||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
await tester.pumpWidget(new Material(
|
await tester.pumpWidget(new Directionality(
|
||||||
child: new ListView(
|
textDirection: TextDirection.ltr,
|
||||||
children: <Widget>[
|
child: new Material(
|
||||||
new Slider(
|
child: new ListView(
|
||||||
value: value,
|
children: <Widget>[
|
||||||
onChanged: (double newValue) {
|
new Slider(
|
||||||
value = newValue;
|
value: value,
|
||||||
},
|
onChanged: (double newValue) {
|
||||||
),
|
value = newValue;
|
||||||
new Container(
|
},
|
||||||
height: 2000.0,
|
),
|
||||||
),
|
new Container(
|
||||||
],
|
height: 2000.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -237,15 +342,18 @@ void main() {
|
|||||||
expect(value, equals(0.5));
|
expect(value, equals(0.5));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Slider drags immediately', (WidgetTester tester) async {
|
testWidgets('Slider drags immediately (LTR)', (WidgetTester tester) async {
|
||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
await tester.pumpWidget(new Material(
|
await tester.pumpWidget(new Directionality(
|
||||||
child: new Center(
|
textDirection: TextDirection.ltr,
|
||||||
child: new Slider(
|
child: new Material(
|
||||||
value: value,
|
child: new Center(
|
||||||
onChanged: (double newValue) {
|
child: new Slider(
|
||||||
value = newValue;
|
value: value,
|
||||||
},
|
onChanged: (double newValue) {
|
||||||
|
value = newValue;
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
@ -262,20 +370,39 @@ void main() {
|
|||||||
await gesture.up();
|
await gesture.up();
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Slider sizing', (WidgetTester tester) async {
|
testWidgets('Slider drags immediately (RTL)', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(const Material(
|
double value = 0.0;
|
||||||
child: const Center(
|
await tester.pumpWidget(new Directionality(
|
||||||
child: const Slider(
|
textDirection: TextDirection.rtl,
|
||||||
value: 0.5,
|
child: new Material(
|
||||||
onChanged: null,
|
child: new Center(
|
||||||
|
child: new Slider(
|
||||||
|
value: value,
|
||||||
|
onChanged: (double newValue) {
|
||||||
|
value = newValue;
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(800.0, 600.0));
|
|
||||||
|
|
||||||
await tester.pumpWidget(const Material(
|
final Offset center = tester.getCenter(find.byType(Slider));
|
||||||
child: const Center(
|
final TestGesture gesture = await tester.startGesture(center);
|
||||||
child: const IntrinsicWidth(
|
|
||||||
|
expect(value, equals(0.5));
|
||||||
|
|
||||||
|
await gesture.moveBy(const Offset(1.0, 0.0));
|
||||||
|
|
||||||
|
expect(value, lessThan(0.5));
|
||||||
|
|
||||||
|
await gesture.up();
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Slider sizing', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(const Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: const Material(
|
||||||
|
child: const Center(
|
||||||
child: const Slider(
|
child: const Slider(
|
||||||
value: 0.5,
|
value: 0.5,
|
||||||
onChanged: null,
|
onChanged: null,
|
||||||
@ -283,16 +410,34 @@ void main() {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(800.0, 600.0));
|
||||||
|
|
||||||
|
await tester.pumpWidget(const Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: const Material(
|
||||||
|
child: const Center(
|
||||||
|
child: const IntrinsicWidth(
|
||||||
|
child: const Slider(
|
||||||
|
value: 0.5,
|
||||||
|
onChanged: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 16.0, 600.0));
|
expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 16.0, 600.0));
|
||||||
|
|
||||||
await tester.pumpWidget(const Material(
|
await tester.pumpWidget(const Directionality(
|
||||||
child: const Center(
|
textDirection: TextDirection.ltr,
|
||||||
child: const OverflowBox(
|
child: const Material(
|
||||||
maxWidth: double.INFINITY,
|
child: const Center(
|
||||||
maxHeight: double.INFINITY,
|
child: const OverflowBox(
|
||||||
child: const Slider(
|
maxWidth: double.INFINITY,
|
||||||
value: 0.5,
|
maxHeight: double.INFINITY,
|
||||||
onChanged: null,
|
child: const Slider(
|
||||||
|
value: 0.5,
|
||||||
|
onChanged: null,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -303,14 +448,15 @@ void main() {
|
|||||||
testWidgets('Slider Semantics', (WidgetTester tester) async {
|
testWidgets('Slider Semantics', (WidgetTester tester) async {
|
||||||
final SemanticsTester semantics = new SemanticsTester(tester);
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(new Directionality(
|
||||||
new Material(
|
textDirection: TextDirection.ltr,
|
||||||
|
child: new Material(
|
||||||
child: new Slider(
|
child: new Slider(
|
||||||
value: 0.5,
|
value: 0.5,
|
||||||
onChanged: (double v) {},
|
onChanged: (double v) {},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
));
|
||||||
|
|
||||||
expect(semantics, hasSemantics(
|
expect(semantics, hasSemantics(
|
||||||
new TestSemantics.root(
|
new TestSemantics.root(
|
||||||
@ -326,14 +472,15 @@ void main() {
|
|||||||
));
|
));
|
||||||
|
|
||||||
// Disable slider
|
// Disable slider
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(new Directionality(
|
||||||
new Material(
|
textDirection: TextDirection.ltr,
|
||||||
|
child: new Material(
|
||||||
child: new Slider(
|
child: new Slider(
|
||||||
value: 0.5,
|
value: 0.5,
|
||||||
onChanged: null,
|
onChanged: null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
));
|
||||||
|
|
||||||
expect(semantics, hasSemantics(
|
expect(semantics, hasSemantics(
|
||||||
new TestSemantics.root(),
|
new TestSemantics.root(),
|
||||||
|
@ -219,13 +219,16 @@ void main() {
|
|||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
new SemanticsDebugger(
|
new SemanticsDebugger(
|
||||||
child: new Material(
|
child: new Directionality(
|
||||||
child: new Center(
|
textDirection: TextDirection.ltr,
|
||||||
child: new Slider(
|
child: new Material(
|
||||||
value: value,
|
child: new Center(
|
||||||
onChanged: (double newValue) {
|
child: new Slider(
|
||||||
value = newValue;
|
value: value,
|
||||||
},
|
onChanged: (double newValue) {
|
||||||
|
value = newValue;
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Loading…
Reference in New Issue
Block a user