Main.java Source code

Java tutorial

Introduction

Here is the source code for Main.java

Source

//package com.java2s;
/*
 * Copyright (c) 2014-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;

import android.widget.AdapterView;
import android.widget.HorizontalScrollView;
import android.widget.ScrollView;
import android.widget.Spinner;
import java.util.List;

public class Main {
    /**
     * Determines if the supplied {@link View} and {@link AccessibilityNodeInfoCompat} has any
     * children which are not independently accessibility focusable and also have a spoken
     * description.
     * <p>
     * NOTE: Accessibility services will include these children's descriptions in the closest
     * focusable ancestor.
     *
     * @param view The {@link View} to evaluate
     * @param node The {@link AccessibilityNodeInfoCompat} to evaluate
     * @return {@code true} if it has any non-actionable speaking descendants within its subtree
     */
    public static boolean hasNonActionableSpeakingDescendants(@Nullable AccessibilityNodeInfoCompat node,
            @Nullable View view) {

        if (node == null || view == null || !(view instanceof ViewGroup)) {
            return false;
        }

        ViewGroup viewGroup = (ViewGroup) view;
        for (int i = 0, count = viewGroup.getChildCount(); i < count; i++) {
            View childView = viewGroup.getChildAt(i);

            if (childView == null) {
                continue;
            }

            AccessibilityNodeInfoCompat childNode = AccessibilityNodeInfoCompat.obtain();
            try {
                ViewCompat.onInitializeAccessibilityNodeInfo(childView, childNode);

                if (isAccessibilityFocusable(childNode, childView)) {
                    continue;
                }

                if (isSpeakingNode(childNode, childView)) {
                    return true;
                }
            } finally {
                childNode.recycle();
            }
        }

        return false;
    }

    /**
     * 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);
    }

    /**
     * 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);
    }

    /**
     * Returns whether a node is actionable. That is, the node supports one of
     * {@link AccessibilityNodeInfoCompat#isClickable()},
     * {@link AccessibilityNodeInfoCompat#isFocusable()}, or
     * {@link AccessibilityNodeInfoCompat#isLongClickable()}.
     *
     * @param node The {@link AccessibilityNodeInfoCompat} to evaluate
     * @return {@code true} if node is actionable.
     */
    public static boolean isActionableForAccessibility(@Nullable AccessibilityNodeInfoCompat node) {
        if (node == null) {
            return false;
        }

        if (node.isClickable() || node.isLongClickable() || node.isFocusable()) {
            return true;
        }

        List actionList = node.getActionList();
        return actionList.contains(AccessibilityNodeInfoCompat.ACTION_CLICK)
                || actionList.contains(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK)
                || actionList.contains(AccessibilityNodeInfoCompat.ACTION_FOCUS);
    }

    /**
     * Determines whether the provided {@link View} and {@link AccessibilityNodeInfoCompat} is a
     * top-level item in a scrollable container.
     *
     * @param view The {@link View} to evaluate
     * @param node The {@link AccessibilityNodeInfoCompat} to evaluate
     * @return {@code true} if it is a top-level item in a scrollable container.
     */
    public static boolean isTopLevelScrollItem(@Nullable AccessibilityNodeInfoCompat node, @Nullable View view) {
        if (node == null || view == null) {
            return false;
        }

        View parent = (View) ViewCompat.getParentForAccessibility(view);
        if (parent == null) {
            return false;
        }

        if (node.isScrollable()) {
            return true;
        }

        List actionList = node.getActionList();
        if (actionList.contains(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD)
                || actionList.contains(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD)) {
            return true;
        }

        // AdapterView, ScrollView, and HorizontalScrollView are focusable
        // containers, but Spinner is a special case.
        if (parent instanceof Spinner) {
            return false;
        }

        return parent instanceof AdapterView || parent instanceof ScrollView
                || parent instanceof HorizontalScrollView;
    }

    /**
     * Returns whether the specified node has text or a content description.
     *
     * @param node The node to check.
     * @return {@code true} if the node has text.
     */
    public static boolean hasText(@Nullable AccessibilityNodeInfoCompat node) {
        if (node == null) {
            return false;
        }

        return !TextUtils.isEmpty(node.getText()) || !TextUtils.isEmpty(node.getContentDescription());
    }
}