[Slider][A11y] Fix slider D-Pad keys to modify value instead of focus

Previously, Up/Down arrow keys navigated focus instead of changing the slider value. This change updates keyboard handling so all D-Pad keys modify the slider value: Up/Down increment/decrement the value, and Left/Right increment/decrement based on layout direction.

PiperOrigin-RevId: 821593460
This commit is contained in:
Material Design Team 2025-10-20 11:46:01 +00:00 committed by Dan Nizri
parent a5be0f7eed
commit aa623f0fac
4 changed files with 78 additions and 32 deletions

View File

@ -3877,20 +3877,18 @@ abstract class BaseSlider<
// Otherwise choose the smallest valid increment.
float increment = isLongPress ? calculateStepIncrement(20) : calculateStepIncrement();
switch (keyCode) {
// Numpad Plus == Shift + Equals, at least in AVD, so fall through.
case KeyEvent.KEYCODE_PLUS:
case KeyEvent.KEYCODE_DPAD_UP:
return isVertical() ? increment : null;
case KeyEvent.KEYCODE_EQUALS:
return increment;
case KeyEvent.KEYCODE_DPAD_DOWN:
return isVertical() ? -increment : null;
case KeyEvent.KEYCODE_MINUS:
return -increment;
case KeyEvent.KEYCODE_DPAD_LEFT:
return isRtl() ? increment : -increment;
case KeyEvent.KEYCODE_DPAD_RIGHT:
return isRtl() ? -increment : increment;
case KeyEvent.KEYCODE_MINUS:
return -increment;
case KeyEvent.KEYCODE_EQUALS:
// Numpad Plus == Shift + Equals, at least in AVD, so fall through.
case KeyEvent.KEYCODE_PLUS:
return increment;
default:
return null;
}

View File

@ -126,30 +126,6 @@ public abstract class SliderKeyTestCommon {
sendKeyEventThereAndBack(tab, shiftTab);
}
@Test
public void testFocusDefaultThumb_clickUpDPad_unhandled() {
slider.requestFocus();
KeyEventBuilder up = new KeyEventBuilder(KeyEvent.KEYCODE_DPAD_UP);
boolean handledDown = slider.dispatchKeyEvent(up.buildDown());
boolean handledUp = slider.dispatchKeyEvent(up.buildUp());
assertThat(handledDown).isFalse();
assertThat(handledUp).isFalse();
}
@Test
public void testFocusDefaultThumb_clickDownDPad_unhandled() {
slider.requestFocus();
KeyEventBuilder down = new KeyEventBuilder(KeyEvent.KEYCODE_DPAD_DOWN);
boolean handledDown = slider.dispatchKeyEvent(down.buildDown());
boolean handledUp = slider.dispatchKeyEvent(down.buildUp());
assertThat(handledDown).isFalse();
assertThat(handledUp).isFalse();
}
@Test
public void testFocusFirstThumb_shiftTab_unhandled() {
slider.requestFocus();
@ -179,6 +155,30 @@ public abstract class SliderKeyTestCommon {
assertThat(handledUp).isFalse();
}
@Test
public void testKeyPress_dPadUp_incrementsValue() {
slider.requestFocus();
slider.setValues(50f);
slider.setStepSize(1f);
KeyEventBuilder up = new KeyEventBuilder(KeyEvent.KEYCODE_DPAD_UP);
up.dispatchEvent(slider);
assertThat(slider.getValues().get(0)).isEqualTo(51f);
}
@Test
public void testKeyPress_dPadDown_decrementsValue() {
slider.requestFocus();
slider.setValues(50f);
slider.setStepSize(1f);
KeyEventBuilder down = new KeyEventBuilder(KeyEvent.KEYCODE_DPAD_DOWN);
down.dispatchEvent(slider);
assertThat(slider.getValues().get(0)).isEqualTo(49f);
}
protected void sendKeyEventThereAndBack(KeyEventBuilder there, KeyEventBuilder back) {
for (int i = 1; i < countTestValues(); i++) {
there.dispatchEvent(slider);

View File

@ -72,4 +72,28 @@ public final class SliderKeyTestLtr extends SliderKeyTestCommon {
assertThat(slider.getValues()).doesNotContain(3.0f);
}
@Test
public void testKeyPress_dPadLeft_decrementsValue() {
slider.requestFocus();
slider.setValues(50f);
slider.setStepSize(1f);
KeyEventBuilder left = new KeyEventBuilder(KeyEvent.KEYCODE_DPAD_LEFT);
left.dispatchEvent(slider);
assertThat(slider.getValues().get(0)).isEqualTo(49f);
}
@Test
public void testKeyPress_dPadRight_incrementsValue() {
slider.requestFocus();
slider.setValues(50f);
slider.setStepSize(1f);
KeyEventBuilder right = new KeyEventBuilder(KeyEvent.KEYCODE_DPAD_RIGHT);
right.dispatchEvent(slider);
assertThat(slider.getValues().get(0)).isEqualTo(51f);
}
}

View File

@ -91,4 +91,28 @@ public final class SliderKeyTestRtl extends SliderKeyTestCommon {
// Moving left increments in RTL.
assertThat(slider.getValues()).doesNotContain(3.0f);
}
@Test
public void testKeyPress_dPadLeft_incrementsValue() {
slider.requestFocus();
slider.setValues(50f);
slider.setStepSize(1f);
KeyEventBuilder left = new KeyEventBuilder(KeyEvent.KEYCODE_DPAD_LEFT);
left.dispatchEvent(slider);
assertThat(slider.getValues().get(0)).isEqualTo(51f);
}
@Test
public void testKeyPress_dPadRight_decrementsValue() {
slider.requestFocus();
slider.setValues(50f);
slider.setStepSize(1f);
KeyEventBuilder right = new KeyEventBuilder(KeyEvent.KEYCODE_DPAD_RIGHT);
right.dispatchEvent(slider);
assertThat(slider.getValues().get(0)).isEqualTo(49f);
}
}