下面列出了android.support.v4.view.accessibility.AccessibilityNodeInfoCompat#performAction ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/** Asks the focused node to navigate at the requested granularity. */
private boolean navigateAtMovementGranularity(int action,
int granularity) {
Bundle arguments = new Bundle();
arguments.putInt(AccessibilityNodeInfoCompat
.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, granularity);
AccessibilityNodeInfoCompat node = getFocusedNode();
if (node == null) {
return false;
}
try {
return node.performAction(action, arguments);
} finally {
node.recycle();
}
}
private boolean moveFocus(AccessibilityNodeInfoCompat from,
int direction) {
int searchDirection = (direction == DIRECTION_BACKWARD)
? FocusFinder.SEARCH_BACKWARD
: FocusFinder.SEARCH_FORWARD;
AccessibilityNodeInfoCompat next = null;
next = mFocusFinder.linear(from, searchDirection);
try {
if (next != null) {
return next.performAction(
AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
}
} finally {
AccessibilityNodeInfoUtils.recycleNodes(next);
}
return false;
}
/**
* Attempts to scroll using the specified action.
*/
private boolean attemptScrollAction(int action) {
AccessibilityNodeInfoCompat focusedNode = null;
AccessibilityNodeInfoCompat scrollableNode = null;
try {
focusedNode = getFocusedNode(false);
if (focusedNode == null) {
return false;
}
scrollableNode =
AccessibilityNodeInfoUtils.getSelfOrMatchingAncestor(
mAccessibilityService, focusedNode,
AccessibilityNodeInfoUtils.FILTER_SCROLLABLE);
if (scrollableNode == null) {
return false;
}
return scrollableNode.performAction(action);
} finally {
AccessibilityNodeInfoUtils.recycleNodes(focusedNode
, scrollableNode);
}
}
/**
* Searches for the next result matching the current search query in the
* specified direction. Ordering of results taken from linear navigation.
* Returns whether there is another result in that direction.
*/
private boolean nextResult(int direction) {
AccessibilityNodeInfoRef next = new AccessibilityNodeInfoRef();
next.reset(NodeFocusFinder.focusSearch(
getCurrentNode(), direction));
AccessibilityNodeInfoCompat focusableNext = null;
try {
while (next.get() != null) {
if (nodeMatchesQuery(next.get())) {
// Even if the text matches, we need to make sure the node
// should be focused or has a parent that should be focused.
focusableNext =
AccessibilityNodeInfoUtils.findFocusFromHover(
mAccessibilityService, next.get());
// Only count this as a match if it doesn't lead to the same
// parent.
if (focusableNext != null &&
!focusableNext.isAccessibilityFocused()) {
break;
}
}
next.reset(NodeFocusFinder.focusSearch(next.get(), direction));
}
if (focusableNext == null) {
return false;
}
mMatchedNode.reset(next);
return focusableNext.performAction(
AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
} finally {
AccessibilityNodeInfoUtils.recycleNodes(focusableNext);
next.recycle();
}
}
/**
* Sets the accessibility focus to the node that currently has
* input focus, if accessibility focus is not already set
* in the currently focused window.
*/
private void setFocusFromInput() {
AccessibilityNodeInfoCompat root =
AccessibilityServiceCompatUtils.getRootInActiveWindow(
mAccessibilityService);
if (root == null) {
return;
}
AccessibilityNodeInfoCompat accessibilityFocused = null;
AccessibilityNodeInfoCompat inputFocused = null;
try {
accessibilityFocused = root.findFocus(
AccessibilityNodeInfoCompat.FOCUS_ACCESSIBILITY);
if (accessibilityFocused != null) {
return;
}
inputFocused = root.findFocus(
AccessibilityNodeInfoCompat.FOCUS_INPUT);
if (inputFocused == null
|| !AccessibilityNodeInfoUtils.shouldFocusNode(
mAccessibilityService, inputFocused)) {
return;
}
inputFocused.performAction(
AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS);
} finally {
AccessibilityNodeInfoUtils.recycleNodes(root, inputFocused,
accessibilityFocused);
}
}
/**
* Attempts to navigate to the top-most focusable node in the tree.
*/
private boolean attemptNavigateTop() {
AccessibilityNodeInfoCompat root =
AccessibilityServiceCompatUtils.getRootInActiveWindow(
mAccessibilityService);
AccessibilityNodeInfoCompat toFocus = null;
if (AccessibilityNodeInfoUtils.shouldFocusNode(
mAccessibilityService, root)) {
toFocus = root;
root = null;
} else {
toFocus = mFocusFinder.linear(root, FocusFinder.SEARCH_FORWARD);
if (toFocus == null) {
// Fall back on root as a last resort.
toFocus = root;
root = null;
}
}
try {
if (toFocus.isAccessibilityFocused()) {
brailleFocusedNode();
return true;
}
return toFocus.performAction(
AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
} finally {
AccessibilityNodeInfoUtils.recycleNodes(root, toFocus);
}
}
/**
* Attempts to navigate to the bottom-most focusable node in the tree.
*/
private boolean attemptNavigateBottom() {
AccessibilityNodeInfoCompat root =
AccessibilityServiceCompatUtils.getRootInActiveWindow(
mAccessibilityService);
AccessibilityNodeInfoCompat toFocus =
FocusFinder.findLastFocusableDescendant(root,
mAccessibilityService);
try {
if (toFocus == null) {
if (AccessibilityNodeInfoUtils.shouldFocusNode(
mAccessibilityService, root)) {
root = null;
toFocus = root;
} else {
return false;
}
}
if (toFocus.isAccessibilityFocused()) {
brailleFocusedNode();
return true;
}
return toFocus.performAction(
AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
} finally {
AccessibilityNodeInfoUtils.recycleNodes(root, toFocus);
}
}
/**
* Sends an instruction to ChromeVox to read the specified HTML element in
* the given direction within a node.
* <p>
* WARNING: Calling this method with a source node of
* {@link android.webkit.WebView} has the side effect of closing the IME
* if currently displayed.
*
* @param node The node containing web content with ChromeVox to which the
* message should be sent
* @param direction {@link #DIRECTION_FORWARD} or
* {@link #DIRECTION_BACKWARD}
* @param htmlElement The HTML tag to send
* @return {@code true} if the action was performed, {@code false}
* otherwise.
*/
public static boolean performNavigationToHtmlElementAction(
AccessibilityNodeInfoCompat node, int direction, String htmlElement) {
final int action = (direction == DIRECTION_FORWARD)
? AccessibilityNodeInfoCompat.ACTION_NEXT_HTML_ELEMENT
: AccessibilityNodeInfoCompat.ACTION_PREVIOUS_HTML_ELEMENT;
final Bundle args = new Bundle();
args.putString(
AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING, htmlElement);
return node.performAction(action, args);
}
/**
* Sends an instruction to ChromeVox to navigate by DOM object in
* the given direction within a node.
*
* @param node The node containing web content with ChromeVox to which the
* message should be sent
* @param direction {@link #DIRECTION_FORWARD} or
* {@link #DIRECTION_BACKWARD}
* @return {@code true} if the action was performed, {@code false}
* otherwise.
*/
public static boolean performNavigationByDOMObject(
AccessibilityNodeInfoCompat node, int direction) {
final int action = (direction == DIRECTION_FORWARD)
? AccessibilityNodeInfoCompat.ACTION_NEXT_HTML_ELEMENT
: AccessibilityNodeInfoCompat.ACTION_PREVIOUS_HTML_ELEMENT;
return node.performAction(action);
}
/**
* Sends an instruction to ChromeVox to move within a page at a specified
* granularity in a given direction.
* <p>
* WARNING: Calling this method with a source node of
* {@link android.webkit.WebView} has the side effect of closing the IME
* if currently displayed.
*
* @param node The node containing web content with ChromeVox to which the
* message should be sent
* @param direction {@link #DIRECTION_FORWARD} or
* {@link #DIRECTION_BACKWARD}
* @param granularity The granularity with which to move or a special case argument.
* @return {@code true} if the action was performed, {@code false} otherwise.
*/
public static boolean performNavigationAtGranularityAction(
AccessibilityNodeInfoCompat node, int direction, int granularity) {
final int action = (direction == DIRECTION_FORWARD)
? AccessibilityNodeInfoCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
: AccessibilityNodeInfoCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
final Bundle args = new Bundle();
args.putInt(
AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, granularity);
return node.performAction(action, args);
}
/**
* Attempts to perform an accessibility action on a view that is an
* instance of the class {@code className}, the text or content
* description {@code text}, and exists under a parent view {@code root}.
*
* @param context The parent context.
* @param root The parent view's node.
* @param className The class name to match.
* @param text The text or content description to match.
* @param action The action to perform.
* @param arguments The action arguments.
* @return {@code true} if the action was performed.
*/
public static boolean performActionOnView(Context context, AccessibilityNodeInfoCompat root,
CharSequence className, String text, int action, Bundle arguments) {
final List<AccessibilityNodeInfoCompat> matches = findViewsWithText(
context, root, className, text);
if (matches.size() != 1) {
return false;
}
final AccessibilityNodeInfoCompat node = matches.get(0);
return node.performAction(action, arguments);
}