mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Missing default focus when navigating to a page with no SemanticsNode that sets namesRoute:true (#20516)
This commit is contained in:
parent
3930ac1b25
commit
ccaee70b05
@ -1548,6 +1548,17 @@ public class AccessibilityBridge extends AccessibilityNodeProvider {
|
||||
AccessibilityEvent event =
|
||||
obtainAccessibilityEvent(route.id, AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
|
||||
String routeName = route.getRouteName();
|
||||
if (routeName == null) {
|
||||
// The routeName will be null when there is no semantics node that represnets namesRoute in
|
||||
// the scopeRoute. The TYPE_WINDOW_STATE_CHANGED only works the route name is not null and not
|
||||
// empty. Gives it a whitespace will make it focus the first semantics node without
|
||||
// pronouncing any word.
|
||||
//
|
||||
// The other way to trigger a focus change is to send a TYPE_VIEW_FOCUSED to the
|
||||
// rootAccessibilityView. However, it is less predictable which semantics node it will focus
|
||||
// next.
|
||||
routeName = " ";
|
||||
}
|
||||
event.getText().add(routeName);
|
||||
sendAccessibilityEvent(event);
|
||||
}
|
||||
|
||||
@ -132,6 +132,41 @@ public class AccessibilityBridgeTest {
|
||||
assertEquals(event.getEventType(), AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itAnnouncesWhiteSpaceWhenNoNamesRoute() {
|
||||
AccessibilityViewEmbedder mockViewEmbedder = mock(AccessibilityViewEmbedder.class);
|
||||
AccessibilityManager mockManager = mock(AccessibilityManager.class);
|
||||
View mockRootView = mock(View.class);
|
||||
Context context = mock(Context.class);
|
||||
when(mockRootView.getContext()).thenReturn(context);
|
||||
when(context.getPackageName()).thenReturn("test");
|
||||
AccessibilityBridge accessibilityBridge =
|
||||
setUpBridge(mockRootView, mockManager, mockViewEmbedder);
|
||||
ViewParent mockParent = mock(ViewParent.class);
|
||||
when(mockRootView.getParent()).thenReturn(mockParent);
|
||||
when(mockManager.isEnabled()).thenReturn(true);
|
||||
|
||||
// Sent a11y tree with scopeRoute without namesRoute.
|
||||
TestSemanticsNode root = new TestSemanticsNode();
|
||||
root.id = 0;
|
||||
TestSemanticsNode scopeRoute = new TestSemanticsNode();
|
||||
scopeRoute.id = 1;
|
||||
scopeRoute.addFlag(AccessibilityBridge.Flag.SCOPES_ROUTE);
|
||||
root.children.add(scopeRoute);
|
||||
TestSemanticsUpdate testSemanticsUpdate = root.toUpdate();
|
||||
accessibilityBridge.updateSemantics(testSemanticsUpdate.buffer, testSemanticsUpdate.strings);
|
||||
|
||||
ArgumentCaptor<AccessibilityEvent> eventCaptor =
|
||||
ArgumentCaptor.forClass(AccessibilityEvent.class);
|
||||
verify(mockParent, times(2))
|
||||
.requestSendAccessibilityEvent(eq(mockRootView), eventCaptor.capture());
|
||||
AccessibilityEvent event = eventCaptor.getAllValues().get(0);
|
||||
assertEquals(event.getEventType(), AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
|
||||
List<CharSequence> sentences = event.getText();
|
||||
assertEquals(sentences.size(), 1);
|
||||
assertEquals(sentences.get(0).toString(), " ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itHoverOverOutOfBoundsDoesNotCrash() {
|
||||
// SementicsNode.hitTest() returns null when out of bounds.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user