mirror of
https://github.com/flutter/flutter
synced 2024-08-27 20:10:11 +00:00
Fix a Slider
widget accessibility bug (#102129)
This commit is contained in:
parent
63574cf76a
commit
2381657394
|
@ -285,7 +285,9 @@ class RangeSlider extends StatefulWidget {
|
|||
/// If null, the slider is continuous.
|
||||
final int? divisions;
|
||||
|
||||
/// Labels to show as text in the [SliderThemeData.rangeValueIndicatorShape].
|
||||
/// Labels to show as text in the [SliderThemeData.rangeValueIndicatorShape]
|
||||
/// when the slider is active and [SliderThemeData.showValueIndicator]
|
||||
/// is satisfied.
|
||||
///
|
||||
/// There are two labels: one for the start thumb and one for the end thumb.
|
||||
///
|
||||
|
@ -1491,7 +1493,6 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix
|
|||
double value,
|
||||
double increasedValue,
|
||||
double decreasedValue,
|
||||
String? label,
|
||||
VoidCallback increaseAction,
|
||||
VoidCallback decreaseAction,
|
||||
) {
|
||||
|
@ -1503,7 +1504,7 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix
|
|||
config.onIncrease = increaseAction;
|
||||
config.onDecrease = decreaseAction;
|
||||
}
|
||||
config.label = label ?? '';
|
||||
|
||||
if (semanticFormatterCallback != null) {
|
||||
config.value = semanticFormatterCallback!(_state._lerp(value));
|
||||
config.increasedValue = semanticFormatterCallback!(_state._lerp(increasedValue));
|
||||
|
@ -1529,7 +1530,6 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix
|
|||
values.start,
|
||||
_increasedStartValue,
|
||||
_decreasedStartValue,
|
||||
labels?.start,
|
||||
_increaseStartAction,
|
||||
_decreaseStartAction,
|
||||
);
|
||||
|
@ -1537,7 +1537,6 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix
|
|||
values.end,
|
||||
_increasedEndValue,
|
||||
_decreasedEndValue,
|
||||
labels?.end,
|
||||
_increaseEndAction,
|
||||
_decreaseEndAction,
|
||||
);
|
||||
|
|
|
@ -317,7 +317,8 @@ class Slider extends StatefulWidget {
|
|||
/// If null, the slider is continuous.
|
||||
final int? divisions;
|
||||
|
||||
/// A label to show above the slider when the slider is active.
|
||||
/// A label to show above the slider when the slider is active and
|
||||
/// [SliderThemeData.showValueIndicator] is satisfied.
|
||||
///
|
||||
/// It is used to display the value of a discrete slider, and it is displayed
|
||||
/// as part of the value indicator shape.
|
||||
|
@ -1506,7 +1507,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
|||
config.onIncrease = increaseAction;
|
||||
config.onDecrease = decreaseAction;
|
||||
}
|
||||
config.label = _label ?? '';
|
||||
|
||||
if (semanticFormatterCallback != null) {
|
||||
config.value = semanticFormatterCallback!(_state._lerp(value));
|
||||
config.increasedValue = semanticFormatterCallback!(_state._lerp((value + _semanticActionUnit).clamp(0.0, 1.0)));
|
||||
|
|
|
@ -1681,6 +1681,65 @@ void main() {
|
|||
);
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/101868
|
||||
testWidgets('RangeSlider.label info should not write to semantic node', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Theme(
|
||||
data: ThemeData.light(),
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Material(
|
||||
child: RangeSlider(
|
||||
values: const RangeValues(10.0, 12.0),
|
||||
max: 100.0,
|
||||
onChanged: (RangeValues v) { },
|
||||
labels: const RangeLabels('Begin', 'End'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(
|
||||
tester.getSemantics(find.byType(RangeSlider)),
|
||||
matchesSemantics(
|
||||
scopesRoute: true,
|
||||
children:<Matcher>[
|
||||
matchesSemantics(
|
||||
children: <Matcher>[
|
||||
matchesSemantics(
|
||||
isEnabled: true,
|
||||
isSlider: true,
|
||||
hasEnabledState: true,
|
||||
hasIncreaseAction: true,
|
||||
hasDecreaseAction: true,
|
||||
value: '10%',
|
||||
increasedValue: '10%',
|
||||
decreasedValue: '5%',
|
||||
label: ''
|
||||
),
|
||||
matchesSemantics(
|
||||
isEnabled: true,
|
||||
isSlider: true,
|
||||
hasEnabledState: true,
|
||||
hasIncreaseAction: true,
|
||||
hasDecreaseAction: true,
|
||||
value: '12%',
|
||||
increasedValue: '17%',
|
||||
decreasedValue: '12%',
|
||||
label: ''
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Range Slider Semantics', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
|
|
|
@ -1816,6 +1816,66 @@ void main() {
|
|||
semantics.dispose();
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/101868
|
||||
testWidgets('Slider.label info should not write to semantic node', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Material(
|
||||
child: Slider(
|
||||
value: 40.0,
|
||||
max: 200.0,
|
||||
divisions: 10,
|
||||
semanticFormatterCallback: (double value) => value.round().toString(),
|
||||
onChanged: (double v) { },
|
||||
label: 'Bingo',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
expect(
|
||||
semantics,
|
||||
hasSemantics(
|
||||
TestSemantics.root(
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
id: 1,
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
id: 2,
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
id: 3,
|
||||
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
id: 4,
|
||||
flags: <SemanticsFlag>[SemanticsFlag.hasEnabledState, SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, SemanticsFlag.isSlider],
|
||||
actions: <SemanticsAction>[SemanticsAction.increase, SemanticsAction.decrease],
|
||||
value: '40',
|
||||
increasedValue: '60',
|
||||
decreasedValue: '20',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
ignoreRect: true,
|
||||
ignoreTransform: true,
|
||||
),
|
||||
);
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Slider is focusable and has correct focus color', (WidgetTester tester) async {
|
||||
final FocusNode focusNode = FocusNode(debugLabel: 'Slider');
|
||||
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
||||
|
|
Loading…
Reference in a new issue