RecyclerView 滑动 无障碍发出流程

203 阅读1分钟
RecyclerView.onTouchEvent() ->
RecyclerView.scrollByInternal()->
RecyclerView.dispatchOnScrolled()->
View.onScrollChanged()
View.postSendViewScrolledAccessibilityEventCallback()>
View.sendAccessibilityEventUnchecked(AccessibilityEvent event)->
RecyclerViewAccessibilityDelegate.sendAccessibilityEventUnchecked()->
host.sendAccessibilityEventUncheckedInternal(event)->(host:View)

View.

public void sendAccessibilityEventUncheckedInternal(AccessibilityEvent event) {
    // Panes disappearing are relevant even if though the view is no longer visible.
    boolean isWindowStateChanged =
            (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
    boolean isWindowDisappearedEvent = isWindowStateChanged && ((event.getContentChangeTypes()
            & AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED) != 0);
    if (!isShown() && !isWindowDisappearedEvent) {
        return;
    }
    桥接到hook方法
    onInitializeAccessibilityEvent(event);
  }

View

@CallSuper
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    if (mAccessibilityDelegate != null) {
        mAccessibilityDelegate.onInitializeAccessibilityEvent(this, event);
    } else {
        onInitializeAccessibilityEventInternal(event);
    }
}

RecyclerViewAccessibilityDelegate.java

@Override
public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(host, event);
    if (host instanceof RecyclerView && !shouldIgnore()) {
        RecyclerView rv = (RecyclerView) host;
        if (rv.getLayoutManager() != null) {
            rv.getLayoutManager().onInitializeAccessibilityEvent(event);
        }
    }
}

LayoutManager

@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(event);
    if (getChildCount() > 0) {
        final View start = findFirstVisibleItemClosestToStart(false);
        final View end = findFirstVisibleItemClosestToEnd(false);
        if (start == null || end == null) {
            return;
        }
        final int startPos = getPosition(start);
        final int endPos = getPosition(end);
        if (startPos < endPos) {
            event.setFromIndex(startPos);
            event.setToIndex(endPos);
        } else {
            event.setFromIndex(endPos);
            event.setToIndex(startPos);
        }
    }
}