下面列出了android.support.v4.view.accessibility.AccessibilityNodeInfoCompat#isVisibleToUser ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Returns whether the supplied {@link View} and {@link AccessibilityNodeInfoCompat} would
* produce spoken feedback if it were accessibility focused. NOTE: not all speaking nodes are
* focusable.
*
* @param view The {@link View} to evaluate
* @param node The {@link AccessibilityNodeInfoCompat} to evaluate
* @return {@code true} if it meets the criterion for producing spoken feedback
*/
public static boolean isSpeakingNode(
@Nullable AccessibilityNodeInfoCompat node,
@Nullable View view) {
if (node == null || view == null) {
return false;
}
if (!node.isVisibleToUser()) {
return false;
}
int important = ViewCompat.getImportantForAccessibility(view);
if (important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS ||
(important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO &&
node.getChildCount() <= 0)) {
return false;
}
return node.isCheckable() || hasText(node) || hasNonActionableSpeakingDescendants(node, view);
}
/**
* Determines if the provided {@link View} and {@link AccessibilityNodeInfoCompat} meet the
* criteria for gaining accessibility focus.
*
* @param view The {@link View} to evaluate
* @param node The {@link AccessibilityNodeInfoCompat} to evaluate
* @return {@code true} if it is possible to gain accessibility focus
*/
public static boolean isAccessibilityFocusable(
@Nullable AccessibilityNodeInfoCompat node,
@Nullable View view) {
if (node == null || view == null) {
return false;
}
// Never focus invisible nodes.
if (!node.isVisibleToUser()) {
return false;
}
// Always focus "actionable" nodes.
if (isActionableForAccessibility(node)) {
return true;
}
// only focus top-level list items with non-actionable speaking children.
return isTopLevelScrollItem(node, view) && isSpeakingNode(node, view);
}
/**
* Formats {@code node} and its descendants, appending the result
* to {@code sb}.
*/
private void formatSubtree(AccessibilityNodeInfoCompat node,
Editable result) {
if (!node.isVisibleToUser()) {
return;
}
BrailleRule rule = mRuleRepository.find(node);
SpannableStringBuilder subtreeResult = new SpannableStringBuilder();
rule.format(subtreeResult, mContext, node);
if (rule.includeChildren(node, mContext)) {
int childCount = node.getChildCount();
for (int i = 0; i < childCount; ++i) {
AccessibilityNodeInfoCompat child = node.getChild(i);
if (child == null) {
continue;
}
formatSubtree(child, subtreeResult);
child.recycle();
}
}
if (!TextUtils.isEmpty(subtreeResult)) {
// If the node is accessibility focused, add the focus span
// here to cover the node and its formatted children.
// This is a fallback in case the formatting rule hasn't set
// focus by itself.
if (node.isAccessibilityFocused()
&& subtreeResult.getSpans(0, subtreeResult.length(),
DisplaySpans.FocusSpan.class).length == 0) {
DisplaySpans.addFocus(subtreeResult, 0,
subtreeResult.length());
}
addNodeSpanForUncovered(node, subtreeResult);
StringUtils.appendWithSpaces(result, subtreeResult);
}
}
private boolean onPanLeftOverflowInternal(DisplayManager.Content content) {
AccessibilityNodeInfoCompat currentNode = null;
AccessibilityNodeInfoCompat firstNode = null;
try {
// If the currently focused node is a web view, we attempt
// to delegate navigation to the web view first.
currentNode = getFocusedNode(true);
if (currentNode != null
&& WebInterfaceUtils.hasLegacyWebContent(currentNode)
&& WebInterfaceUtils.performNavigationAtGranularityAction(
currentNode, DIRECTION_BACKWARD,
AccessibilityNodeInfoCompat
.MOVEMENT_GRANULARITY_LINE)) {
return true;
}
// Check if we need to scroll.
if (autoScrollItem(currentNode,
AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)) {
return true;
}
firstNode = AccessibilityNodeInfoUtils.refreshNode(
content.getFirstNode());
// If the content doesn't have a first node, fall back on the
// currently focused node.
if (firstNode == null || !firstNode.isVisibleToUser()) {
AccessibilityNodeInfoUtils.recycleNodes(firstNode);
firstNode = currentNode;
currentNode = null;
}
if (firstNode == null) {
return false;
}
return moveFocus(firstNode, DIRECTION_BACKWARD);
} finally {
AccessibilityNodeInfoUtils.recycleNodes(currentNode, firstNode);
}
}
public static String getIgnoredReasons(View view) {
int important = ViewCompat.getImportantForAccessibility(view);
if (important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO) {
return "View has importantForAccessibility set to 'NO'.";
}
if (important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
return "View has importantForAccessibility set to 'NO_HIDE_DESCENDANTS'.";
}
ViewParent parent = view.getParent();
while (parent instanceof View) {
if (ViewCompat.getImportantForAccessibility((View) parent)
== ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
return "An ancestor View has importantForAccessibility set to 'NO_HIDE_DESCENDANTS'.";
}
parent = parent.getParent();
}
AccessibilityNodeInfoCompat node = createNodeInfoFromView(view);
try {
if (!node.isVisibleToUser()) {
return "View is not visible.";
}
if (AccessibilityUtil.isAccessibilityFocusable(node, view)) {
return "View is actionable, but has no description.";
}
if (AccessibilityUtil.hasText(node)) {
return "View is not actionable, and an ancestor View has co-opted its description.";
}
return "View is not actionable and has no description.";
} finally {
node.recycle();
}
}
/**
* Gets a description of the properties of a node.
*/
public static CharSequence nodeDebugDescription(AccessibilityNodeInfoCompat node) {
StringBuilder sb = new StringBuilder();
sb.append(node.getWindowId());
if (node.getClassName() != null) {
appendSimpleName(sb, node.getClassName());
} else {
sb.append("??");
}
if (!node.isVisibleToUser()) {
sb.append(":invisible");
}
if (node.getText() != null) {
sb.append(":");
sb.append(node.getText().toString().trim());
}
if (node.getContentDescription() != null) {
sb.append(":");
sb.append(node.getContentDescription().toString().trim());
}
int actions = node.getActions();
if (actions != 0) {
sb.append(":");
if ((actions & AccessibilityNodeInfoCompat.ACTION_FOCUS) != 0) {
sb.append("F");
}
if ((actions & AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS) != 0) {
sb.append("A");
}
if ((actions & AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS) != 0) {
sb.append("a");
}
if ((actions & AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD) != 0) {
sb.append("-");
}
if ((actions & AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD) != 0) {
sb.append("+");
}
}
if (node.isCheckable()) {
sb.append(":");
if (node.isChecked()) {
sb.append("(X)");
} else {
sb.append("( )");
}
}
if (node.isFocusable()) {
sb.append(":focusable");
}
if (node.isFocused()) {
sb.append(":focused");
}
if (node.isSelected()) {
sb.append(":selected");
}
if (node.isClickable()) {
sb.append(":clickable");
}
if (node.isLongClickable()) {
sb.append(":longClickable");
}
if (node.isAccessibilityFocused()) {
sb.append(":accessibilityFocused");
}
if (!node.isEnabled()) {
sb.append(":disabled");
}
return sb.toString();
}
public static boolean getIgnored(View view) {
int important = ViewCompat.getImportantForAccessibility(view);
if (important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO ||
important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
return true;
}
// Go all the way up the tree to make sure no parent has hidden its descendants
ViewParent parent = view.getParent();
while (parent instanceof View) {
if (ViewCompat.getImportantForAccessibility((View) parent)
== ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
return true;
}
parent = parent.getParent();
}
AccessibilityNodeInfoCompat node = createNodeInfoFromView(view);
try {
if (!node.isVisibleToUser()) {
return true;
}
if (AccessibilityUtil.isAccessibilityFocusable(node, view)) {
if (node.getChildCount() <= 0) {
// Leaves that are accessibility focusable are never ignored, even if they don't have a
// speakable description
return false;
} else if (AccessibilityUtil.isSpeakingNode(node, view)) {
// Node is focusable and has something to speak
return false;
}
// Node is focusable and has nothing to speak
return true;
}
// If this node has no focusable ancestors, but it still has text,
// then it should receive focus from navigation and be read aloud.
if (!AccessibilityUtil.hasFocusableAncestor(node, view) && AccessibilityUtil.hasText(node)) {
return false;
}
return true;
} finally {
node.recycle();
}
}
/**
* Helper method that returns {@code true} if the specified node is visible
* to the user or if the current SDK doesn't support checking visibility.
*/
public static boolean isVisibleOrLegacy(AccessibilityNodeInfoCompat node) {
return (!AccessibilityNodeInfoUtils.SUPPORTS_VISIBILITY || node.isVisibleToUser());
}