Slider.onChangeStart
& Slider.onChangeEnd
are not called on keyboard shortcuts (#126896)
fixes https://github.com/flutter/flutter/issues/123315 -------- This PR makes changes to the _actionHandler function used on the Slider.Dart Widget for Key Events. It ensures onChangeStart is called at the beginning of a Key Event and onChangeEnd at the end of one. This PR includes a test for the changes made. I ran all existing tests after my changes were made and they passed.
This commit is contained in:
parent
982e00527c
commit
5451ea6e8f
@ -684,6 +684,7 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin {
|
|||||||
void _actionHandler(_AdjustSliderIntent intent) {
|
void _actionHandler(_AdjustSliderIntent intent) {
|
||||||
final _RenderSlider renderSlider = _renderObjectKey.currentContext!.findRenderObject()! as _RenderSlider;
|
final _RenderSlider renderSlider = _renderObjectKey.currentContext!.findRenderObject()! as _RenderSlider;
|
||||||
final TextDirection textDirection = Directionality.of(_renderObjectKey.currentContext!);
|
final TextDirection textDirection = Directionality.of(_renderObjectKey.currentContext!);
|
||||||
|
|
||||||
switch (intent.type) {
|
switch (intent.type) {
|
||||||
case _SliderAdjustmentType.right:
|
case _SliderAdjustmentType.right:
|
||||||
switch (textDirection) {
|
switch (textDirection) {
|
||||||
@ -1802,15 +1803,33 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
|||||||
|
|
||||||
void increaseAction() {
|
void increaseAction() {
|
||||||
if (isInteractive) {
|
if (isInteractive) {
|
||||||
onChanged!(clampDouble(value + _semanticActionUnit, 0.0, 1.0));
|
onChangeStart!(currentValue);
|
||||||
|
final double increase = increaseValue();
|
||||||
|
onChanged!(increase);
|
||||||
|
onChangeEnd!(increase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void decreaseAction() {
|
void decreaseAction() {
|
||||||
if (isInteractive) {
|
if (isInteractive) {
|
||||||
onChanged!(clampDouble(value - _semanticActionUnit, 0.0, 1.0));
|
onChangeStart!(currentValue);
|
||||||
|
final double decrease = decreaseValue();
|
||||||
|
onChanged!(decrease);
|
||||||
|
onChangeEnd!(decrease);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double get currentValue {
|
||||||
|
return clampDouble(value, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double increaseValue() {
|
||||||
|
return clampDouble(value + _semanticActionUnit, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double decreaseValue() {
|
||||||
|
return clampDouble(value - _semanticActionUnit, 0.0, 1.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AdjustSliderIntent extends Intent {
|
class _AdjustSliderIntent extends Intent {
|
||||||
|
@ -2125,17 +2125,29 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Slider can be incremented and decremented by keyboard shortcuts - LTR', (WidgetTester tester) async {
|
testWidgets('Slider can be incremented and decremented by keyboard shortcuts - LTR', (WidgetTester tester) async {
|
||||||
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
||||||
double value = 0.5;
|
double startValue = 0.0;
|
||||||
|
double currentValue = 0.5;
|
||||||
|
double endValue = 0.0;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
||||||
return Slider(
|
return Slider(
|
||||||
value: value,
|
value: currentValue,
|
||||||
|
onChangeStart: (double newValue) {
|
||||||
|
setState(() {
|
||||||
|
startValue = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
onChanged: (double newValue) {
|
onChanged: (double newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
value = newValue;
|
currentValue = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onChangeEnd: (double newValue) {
|
||||||
|
setState(() {
|
||||||
|
endValue = newValue;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@ -2149,34 +2161,54 @@ void main() {
|
|||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.55);
|
expect(startValue, 0.5);
|
||||||
|
expect(currentValue, 0.55);
|
||||||
|
expect(endValue, 0.55);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.5);
|
expect(startValue, 0.55);
|
||||||
|
expect(currentValue, 0.5);
|
||||||
|
expect(endValue, 0.5);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.55);
|
expect(startValue, 0.5);
|
||||||
|
expect(currentValue, 0.55);
|
||||||
|
expect(endValue, 0.55);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.5);
|
expect(startValue, 0.55);
|
||||||
|
expect(currentValue, 0.5);
|
||||||
|
expect(endValue, 0.5);
|
||||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.linux, TargetPlatform.windows }));
|
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.linux, TargetPlatform.windows }));
|
||||||
|
|
||||||
testWidgets('Slider can be incremented and decremented by keyboard shortcuts - LTR', (WidgetTester tester) async {
|
testWidgets('Slider can be incremented and decremented by keyboard shortcuts - LTR', (WidgetTester tester) async {
|
||||||
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
||||||
double value = 0.5;
|
double startValue = 0.0;
|
||||||
|
double currentValue = 0.5;
|
||||||
|
double endValue = 0.0;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
||||||
return Slider(
|
return Slider(
|
||||||
value: value,
|
value: currentValue,
|
||||||
|
onChangeStart: (double newValue) {
|
||||||
|
setState(() {
|
||||||
|
startValue = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
onChanged: (double newValue) {
|
onChanged: (double newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
value = newValue;
|
currentValue = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onChangeEnd: (double newValue) {
|
||||||
|
setState(() {
|
||||||
|
endValue = newValue;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@ -2190,24 +2222,34 @@ void main() {
|
|||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.6);
|
expect(startValue, 0.5);
|
||||||
|
expect(currentValue, 0.6);
|
||||||
|
expect(endValue, 0.6);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.5);
|
expect(startValue, 0.6);
|
||||||
|
expect(currentValue, 0.5);
|
||||||
|
expect(endValue, 0.5);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.6);
|
expect(startValue, 0.5);
|
||||||
|
expect(currentValue, 0.6);
|
||||||
|
expect(endValue, 0.6);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.5);
|
expect(startValue, 0.6);
|
||||||
|
expect(currentValue, 0.5);
|
||||||
|
expect(endValue, 0.5);
|
||||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||||
|
|
||||||
testWidgets('Slider can be incremented and decremented by keyboard shortcuts - RTL', (WidgetTester tester) async {
|
testWidgets('Slider can be incremented and decremented by keyboard shortcuts - RTL', (WidgetTester tester) async {
|
||||||
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
||||||
double value = 0.5;
|
double startValue = 0.0;
|
||||||
|
double currentValue = 0.5;
|
||||||
|
double endValue = 0.0;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
@ -2216,10 +2258,20 @@ void main() {
|
|||||||
return Directionality(
|
return Directionality(
|
||||||
textDirection: TextDirection.rtl,
|
textDirection: TextDirection.rtl,
|
||||||
child: Slider(
|
child: Slider(
|
||||||
value: value,
|
value: currentValue,
|
||||||
|
onChangeStart: (double newValue) {
|
||||||
|
setState(() {
|
||||||
|
startValue = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
onChanged: (double newValue) {
|
onChanged: (double newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
value = newValue;
|
currentValue = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onChangeEnd: (double newValue) {
|
||||||
|
setState(() {
|
||||||
|
endValue = newValue;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@ -2234,24 +2286,34 @@ void main() {
|
|||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.45);
|
expect(startValue, 0.5);
|
||||||
|
expect(currentValue, 0.45);
|
||||||
|
expect(endValue, 0.45);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.5);
|
expect(startValue, 0.45);
|
||||||
|
expect(currentValue, 0.5);
|
||||||
|
expect(endValue, 0.5);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.55);
|
expect(startValue, 0.5);
|
||||||
|
expect(currentValue, 0.55);
|
||||||
|
expect(endValue, 0.55);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.5);
|
expect(startValue, 0.55);
|
||||||
|
expect(currentValue, 0.5);
|
||||||
|
expect(endValue, 0.5);
|
||||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.linux, TargetPlatform.windows }));
|
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.linux, TargetPlatform.windows }));
|
||||||
|
|
||||||
testWidgets('Slider can be incremented and decremented by keyboard shortcuts - RTL', (WidgetTester tester) async {
|
testWidgets('Slider can be incremented and decremented by keyboard shortcuts - RTL', (WidgetTester tester) async {
|
||||||
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
||||||
double value = 0.5;
|
double startValue = 0.0;
|
||||||
|
double currentValue = 0.5;
|
||||||
|
double endValue = 0.0;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Material(
|
home: Material(
|
||||||
@ -2260,10 +2322,20 @@ void main() {
|
|||||||
return Directionality(
|
return Directionality(
|
||||||
textDirection: TextDirection.rtl,
|
textDirection: TextDirection.rtl,
|
||||||
child: Slider(
|
child: Slider(
|
||||||
value: value,
|
value: currentValue,
|
||||||
|
onChangeStart: (double newValue) {
|
||||||
|
setState(() {
|
||||||
|
startValue = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
onChanged: (double newValue) {
|
onChanged: (double newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
value = newValue;
|
currentValue = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onChangeEnd: (double newValue) {
|
||||||
|
setState(() {
|
||||||
|
endValue = newValue;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@ -2278,19 +2350,27 @@ void main() {
|
|||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.4);
|
expect(startValue, 0.5);
|
||||||
|
expect(currentValue, 0.4);
|
||||||
|
expect(endValue, 0.4);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.5);
|
expect(startValue, 0.4);
|
||||||
|
expect(currentValue, 0.5);
|
||||||
|
expect(endValue, 0.5);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.6);
|
expect(startValue, 0.5);
|
||||||
|
expect(currentValue, 0.6);
|
||||||
|
expect(endValue, 0.6);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(value, 0.5);
|
expect(startValue, 0.6);
|
||||||
|
expect(currentValue, 0.5);
|
||||||
|
expect(endValue, 0.5);
|
||||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||||
|
|
||||||
testWidgets('In directional nav, Slider can be navigated out of by using up and down arrows', (WidgetTester tester) async {
|
testWidgets('In directional nav, Slider can be navigated out of by using up and down arrows', (WidgetTester tester) async {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user