Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b042a3f

Browse files
committed
a11y: Add SemanticsAction "showOnScreen"
This action is triggered when the user swipes (in accessibility mode) to the last visible item of a scrollable list to bring that item fully on screen. iOS implementation to follow.
1 parent a4fa558 commit b042a3f

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

lib/ui/semantics.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class SemanticsAction {
1717
static const int _kScrollDownIndex = 1 << 5;
1818
static const int _kIncreaseIndex = 1 << 6;
1919
static const int _kDecreaseIndex = 1 << 7;
20+
static const int _kShowOnScreen = 1 << 8;
2021

2122
/// The numerical value for this action.
2223
///
@@ -69,6 +70,12 @@ class SemanticsAction {
6970
/// For example, this action might be recognized by a slider control.
7071
static const SemanticsAction decrease = const SemanticsAction._(_kDecreaseIndex);
7172

73+
/// A request to fully show the semantics node on screen.
74+
///
75+
/// For example, this action might be send to a node in a scrollable list that
76+
/// is partially off screen to bring it on screen.
77+
static const SemanticsAction showOnScreen = const SemanticsAction._(_kShowOnScreen);
78+
7279
/// The possible semantics actions.
7380
///
7481
/// The map's key is the [index] of the action and the value is the action
@@ -82,6 +89,7 @@ class SemanticsAction {
8289
_kScrollDownIndex: scrollDown,
8390
_kIncreaseIndex: increase,
8491
_kDecreaseIndex: decrease,
92+
_kShowOnScreen: showOnScreen,
8593
};
8694

8795
@override
@@ -103,6 +111,8 @@ class SemanticsAction {
103111
return 'SemanticsAction.increase';
104112
case _kDecreaseIndex:
105113
return 'SemanticsAction.decrease';
114+
case _kShowOnScreen:
115+
return 'SemanticsAction.showOnScreen';
106116
}
107117
return null;
108118
}

shell/platform/android/io/flutter/view/AccessibilityBridge.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class AccessibilityBridge extends AccessibilityNodeProvider {
4040
private static final int SEMANTICS_ACTION_SCROLL_DOWN = 1 << 5;
4141
private static final int SEMANTICS_ACTION_INCREASE = 1 << 6;
4242
private static final int SEMANTICS_ACTION_DECREASE = 1 << 7;
43+
private static final int SEMANTICS_ACTION_SHOW_ON_SCREEN = 1 << 8;
4344

4445
private static final int SEMANTICS_ACTION_SCROLLABLE = SEMANTICS_ACTION_SCROLL_LEFT |
4546
SEMANTICS_ACTION_SCROLL_RIGHT |
@@ -77,7 +78,7 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
7778

7879
AccessibilityNodeInfo result = AccessibilityNodeInfo.obtain(mOwner, virtualViewId);
7980
result.setPackageName(mOwner.getContext().getPackageName());
80-
result.setClassName("Flutter"); // Prettier than the more conventional node.getClass().getName()
81+
result.setClassName("Flutter"); // TODO(goderbauer): Set proper class names
8182
result.setSource(mOwner, virtualViewId);
8283

8384
if (object.parent != null) {
@@ -117,6 +118,9 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
117118
result.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
118119
result.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
119120
result.setScrollable(true);
121+
// This tells Android's a11y to send scroll events when reaching the end of
122+
// the visible viewport of a scrollable.
123+
result.setClassName("android.widget.ScrollView");
120124
}
121125

122126
result.setCheckable((object.flags & SEMANTICS_FLAG_HAS_CHECKED_STATE) != 0);
@@ -148,6 +152,7 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
148152

149153
@Override
150154
public boolean performAction(int virtualViewId, int action, Bundle arguments) {
155+
Log.i(TAG, "action: " + action + " , node: " + virtualViewId);
151156
SemanticsObject object = mObjects.get(virtualViewId);
152157
if (object == null) {
153158
return false;
@@ -199,6 +204,12 @@ public boolean performAction(int virtualViewId, int action, Bundle arguments) {
199204
mFocusedObject = object;
200205
return true;
201206
}
207+
// TODO(goderbauer): Use ACTION_SHOW_ON_SCREEN from Android Support Library after
208+
// https://github.com/flutter/flutter/issues/11099 is resolved.
209+
case 16908342: { // ACTION_SHOW_ON_SCREEN, added in API level 23
210+
mOwner.dispatchSemanticsAction(virtualViewId, SEMANTICS_ACTION_SHOW_ON_SCREEN);
211+
return true;
212+
}
202213
}
203214
return false;
204215
}

0 commit comments

Comments
 (0)