下面列出了android.support.v4.view.accessibility.AccessibilityNodeInfoCompat#getChild ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static AccessibilityNodeInfoCompat refreshFromChild(
AccessibilityNodeInfoCompat node) {
if (node.getChildCount() > 0) {
AccessibilityNodeInfoCompat firstChild = node.getChild(0);
if (firstChild != null) {
AccessibilityNodeInfoCompat parent = firstChild.getParent();
firstChild.recycle();
if (node.equals(parent)) {
return parent;
} else {
recycleNodes(parent);
}
}
}
return null;
}
private static AccessibilityNodeInfoCompat refreshFromParent(
AccessibilityNodeInfoCompat node) {
AccessibilityNodeInfoCompat parent = node.getParent();
if (parent != null) {
try {
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; ++i) {
AccessibilityNodeInfoCompat child = parent.getChild(i);
if (node.equals(child)) {
return child;
}
recycleNodes(child);
}
} finally {
parent.recycle();
}
}
return null;
}
private static void logNodeTree(AccessibilityNodeInfoCompat node, String indent,
HashSet<AccessibilityNodeInfoCompat> seen) {
if (!seen.add(node)) {
LogUtils.log(TreeDebug.class, Log.VERBOSE, "Cycle: %d", node.hashCode());
return;
}
// Include the hash code as a "poor man's" id, knowing that it
// might not always be unique.
LogUtils.log(TreeDebug.class, Log.VERBOSE, "%s(%d)%s", indent, node.hashCode(),
nodeDebugDescription(node));
indent += " ";
int childCount = node.getChildCount();
for (int i = 0; i < childCount; ++i) {
AccessibilityNodeInfoCompat child = node.getChild(i);
if (child == null) {
LogUtils.log(TreeDebug.class, Log.VERBOSE, "%sCouldn't get child %d", indent, i);
continue;
}
logNodeTree(child, indent, seen);
}
}
/**
* Returns the result of applying a filter using breadth-first traversal.
*
* @param context The parent context.
* @param node The root node to traverse from.
* @param filter The filter to satisfy.
* @return The first node reached via BFS traversal that satisfies the
* filter.
*/
public static AccessibilityNodeInfoCompat searchFromBfs(
Context context, AccessibilityNodeInfoCompat node, NodeFilter filter) {
if (node == null) {
return null;
}
final LinkedList<AccessibilityNodeInfoCompat> queue =
new LinkedList<AccessibilityNodeInfoCompat>();
queue.add(AccessibilityNodeInfoCompat.obtain(node));
while (!queue.isEmpty()) {
final AccessibilityNodeInfoCompat item = queue.removeFirst();
if (filter.accept(context, item)) {
return AccessibilityNodeInfoCompat.obtain(item);
}
final int childCount = item.getChildCount();
for (int i = 0; i < childCount; i++) {
final AccessibilityNodeInfoCompat child = item.getChild(i);
if (child != null) {
queue.addLast(child);
}
}
}
return null;
}
/**
* Returns the result of applying a filter using breadth-first traversal.
*
* @param context The parent context.
* @param node The root node to traverse from.
* @param filter The filter to satisfy.
* @param maxResults The number of results to stop searching after
* @return Returns all nodes reached via BFS traversal that satisfies the
* filter.
*/
public static List<AccessibilityNodeInfoCompat> searchAllFromBfs(Context context,
AccessibilityNodeInfoCompat node, NodeFilter filter) {
if (node == null) {
return null;
}
final List<AccessibilityNodeInfoCompat> toReturn =
new ArrayList<AccessibilityNodeInfoCompat>();
final LinkedList<AccessibilityNodeInfoCompat> queue =
new LinkedList<AccessibilityNodeInfoCompat>();
queue.add(AccessibilityNodeInfoCompat.obtain(node));
while (!queue.isEmpty()) {
final AccessibilityNodeInfoCompat item = queue.removeFirst();
if (filter.accept(context, item)) {
toReturn.add(AccessibilityNodeInfoCompat.obtain(item));
}
final int childCount = item.getChildCount();
for (int i = 0; i < childCount; i++) {
final AccessibilityNodeInfoCompat child = item.getChild(i);
if (child != null) {
queue.addLast(child);
}
}
}
return toReturn;
}
/**
* Traverses to the previous sibling of this node within its parent,
* returning {@code true} on success.
*/
public boolean previousSibling() {
if (mNode == null) {
return false;
}
AccessibilityNodeInfoCompat parent = mNode.getParent();
if (parent == null) {
return false;
}
try {
int childNumber = getChildNumber(parent);
for (int i = childNumber - 1; i >= 0; --i) {
AccessibilityNodeInfoCompat newNode = parent.getChild(i);
if (newNode == null) {
return false;
}
if (AccessibilityNodeInfoUtils.isVisibleOrLegacy(newNode)) {
reset(newNode);
return true;
}
newNode.recycle();
}
} finally {
parent.recycle();
}
return false;
}
/**
* Traverses to the next sibling of this node within its parent, returning
* {@code true} on success.
*/
public boolean nextSibling() {
if (mNode == null) {
return false;
}
AccessibilityNodeInfoCompat parent = mNode.getParent();
if (parent == null) {
return false;
}
try {
int childCount = parent.getChildCount();
int childNumber = getChildNumber(parent);
if (childNumber < 0) {
return false;
}
for (int i = childNumber + 1; i < childCount; ++i) {
AccessibilityNodeInfoCompat newNode =
parent.getChild(i);
if (newNode == null) {
return false;
}
if (AccessibilityNodeInfoUtils.isVisibleOrLegacy(newNode)) {
reset(newNode);
return true;
}
newNode.recycle();
}
} finally {
parent.recycle();
}
return false;
}
private int getChildNumber(AccessibilityNodeInfoCompat parent) {
int ret = -1;
int childCount = parent.getChildCount();
for (int i = 0; i < childCount && ret < 0; ++i) {
AccessibilityNodeInfoCompat child = parent.getChild(i);
if (mNode.equals(child)) {
ret = i;
}
if (child != null) {
child.recycle();
}
}
return ret;
}
/**
* 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 static AccessibilityNodeInfoCompat
findFirstFocusableDescendantInternal(
AccessibilityNodeInfoCompat root, Context context,
HashSet<AccessibilityNodeInfoCompat> seenNodes) {
for (int i = 0, end = root.getChildCount(); i < end; ++i) {
AccessibilityNodeInfoCompat child = root.getChild(i);
if (child == null) {
continue;
}
if (AccessibilityNodeInfoUtils.shouldFocusNode(
context, child)) {
return child;
}
if (!seenNodes.add(child)) {
LogUtils.log(FocusFinder.class, Log.ERROR,
"Cycle in node tree");
child.recycle();
return null;
}
AccessibilityNodeInfoCompat n =
findFirstFocusableDescendantInternal(
child, context, seenNodes);
if (n != null) {
return n;
}
}
return null;
}
private static AccessibilityNodeInfoCompat
findLastFocusableDescendantInternal(
AccessibilityNodeInfoCompat root, Context context,
HashSet<AccessibilityNodeInfoCompat> seenNodes) {
for (int end = root.getChildCount(), i = end - 1; i >= 0; --i) {
AccessibilityNodeInfoCompat child = root.getChild(i);
if (child == null) {
continue;
}
AccessibilityNodeInfoCompat n =
findLastFocusableDescendantInternal(
child, context, seenNodes);
if (n != null) {
return n;
}
if (AccessibilityNodeInfoUtils.shouldFocusNode(context, child)) {
return child;
}
if (!seenNodes.add(child)) {
LogUtils.log(FocusFinder.class, Log.ERROR,
"Cycle in node tree");
child.recycle();
return null;
}
}
return null;
}
private static boolean hasNonActionableSpeakingChildren(
Context context, AccessibilityNodeInfoCompat node) {
final int childCount = node.getChildCount();
AccessibilityNodeInfoCompat child = null;
// Has non-actionable, speaking children?
for (int i = 0; i < childCount; i++) {
try {
child = node.getChild(i);
if (child == null) {
LogUtils.log(AccessibilityNodeInfoUtils.class, Log.VERBOSE,
"Child %d is null, skipping it", i);
continue;
}
// Ignore invisible nodes.
if (!isVisibleOrLegacy(child)) {
LogUtils.log(AccessibilityNodeInfoUtils.class, Log.VERBOSE,
"Child %d is invisible, skipping it", i);
continue;
}
// Ignore focusable nodes.
if (FILTER_ACCESSIBILITY_FOCUSABLE.accept(context, child)) {
LogUtils.log(AccessibilityNodeInfoUtils.class, Log.VERBOSE,
"Child %d is focusable, skipping it", i);
continue;
}
// Recursively check non-focusable child nodes.
// TODO: Mutual recursion is probably not a good idea.
if (isSpeakingNode(context, child)) {
LogUtils.log(AccessibilityNodeInfoUtils.class, Log.VERBOSE,
"Does have actionable speaking children (child %d)", i);
return true;
}
} finally {
AccessibilityNodeInfoUtils.recycleNodes(child);
}
}
LogUtils.log(AccessibilityNodeInfoUtils.class, Log.VERBOSE,
"Does not have non-actionable speaking children");
return false;
}