-
Notifications
You must be signed in to change notification settings - Fork 55
Virtual accessibility node hierarchies
An accessibility node tree can match its corresponding view hierarchy, but it doesn't have to. Certain complex views, like a chart, can draw their items directly on Canvas, and handle input events without any additional view hierarchy. Such a view should provide a virtual accessibility node hierarchy to expose its internal structure to the accessibility framework. Accessibility nodes can be provided directly by the view or using an AccessibilityDelegate object.
While implementing a custom AccessibilityNodeInfo hierarchy is possible, it can be a quite frustrating and time-consuming task because of the lacking documentation, lots of details, and a very specific testing process. A much easier approach involves using ExploreByTouchHelper and implementing a couple of methods used to generate nodes, handle events, and respond to touch exploration. Setup is very simple and provided by the documentation:
class MyCustomView extends View {
private MyExploreByTouchHelper mExploreByTouchHelper;
public MyCustomView(Context context) {
mExploreByTouchHelper = new MyExploreByTouchHelper(this);
ViewCompat.setAccessibilityDelegate(this, mExploreByTouchHelper);
}
@Override
public boolean dispatchHoverEvent(MotionEvent event) {
return mHelper.dispatchHoverEvent(this, event)
|| super.dispatchHoverEvent(event);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
return mHelper.dispatchKeyEvent(event)
|| super.dispatchKeyEvent(event);
}
@Override
public void onFocusChanged(boolean gainFocus, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
mHelper.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
}
}
Then you have to implement the abstract methods of the helper:
-
int getVirtualViewAt(float x, float y)
to return a virtual child when found by the touch exploration, -
void getVisibleVirtualViews(List<Integer> virtualViewIds)
to populate the list of children, -
void onPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfoCompat node)
to fill the node structure for a child, - and
boolean onPerformActionForVirtualView(int virtualViewId, int action, Bundle arguments)
to perform an action on the virtual child.
An example implementation can be found here.