laplasz
laplasz

Reputation: 3497

android Accessibility focusSearch does not return any node

My Accessibility service would go through the focusable nodes. I am trying to use the focusSearch function for this, but that is not giving any node back. But the layout contains focusable items. Here is the layout:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:focusable="true"
        android:text="Button" />

    <TextView
        android:id="@+id/text"
        android:layout_width="122dp"
        android:layout_height="fill_parent"
        android:text="Hello World2" />

        <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:focusable="true"
        android:text="Button2" />


</LinearLayout>

So what I tried is to find the first button:

AccessibilityNodeInfo root = getRootInActiveWindow();
AccessibilityNodeInfo node1 = null;
node1 = root.findAccessibilityNodeInfosByViewId("my.app:id/button1").get(0);
//returns button view
node1 = root.focusSearch(View.FOCUS_DOWN); //returns null
node1 = root.focusSearch(View.FOCUS_LEFT); //returns null
node1 = root.focusSearch(View.FOCUS_RIGHT); //returns null
node1 = root.focusSearch(View.FOCUS_FORWARD); //returns null

However using findFocus it gives back the framelayout

node1 = root.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
//returns node of the main framelayout

Then I used this node for next search, but nothing found again.

node1 = node1.focusSearch(View.FOCUS_FORWARD); //returns null

And when I call findfocus instead of focusSearch i got the same node back

node1 = node1.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
//returns the same node

So the question is how can I go through on the focusable nodes within a layout?

Upvotes: 1

Views: 2652

Answers (2)

Prasad Pawar
Prasad Pawar

Reputation: 1701

Exactly! The view containers are returned because they are present in the tree.

What you need is the leaf nodes.

This code will give you a list of nodes(leaf nodes) that are focusable:

ArrayList<AccessibilityNodeInfo> inputViewsList = new ArrayList<AccessibilityNodeInfo>();
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
refreshChildViewsList(rootNode);
for(AccessibilityNodeInfo mNode : inputViewsList){
    if(mNode.isFocusable()){
        //do whatever you want with the node...
    }
}

refreshChildViewsList method:

private void refreshChildViews(AccessibilityNodeInfo rootNode){
    int childCount = rootNode.getChildCount();
    for(int i=0; i<childCount ; i++){
        AccessibilityNodeInfo tmpNode = rootNode.getChildAt(i);
        int subChildCount = tmpNode.getChildCount();
        if(subChildCount==0){
            inputViewsList.add(tmpNode);
            return; 
        } else {
            refreshChildViews(tmpNode);
        } 
    } 
} 

Let me know if there's any issue with this code!

Upvotes: 1

MobA11y
MobA11y

Reputation: 18870

This is a common misconception. What you are searching for is objects that can take input focus (think EditText controls). This is fundamentally different from Accessibility Focus. There are no input focusable controls in your layout.

The functions you want are:

someAccessibilityNodeInfo.getTraversalAfter();

and

someAccessibilityNodeInfo.getTraversalBefore();

There is no up/down equivalent. Though you could calculate this however you want. You could store the entire heirarchy of accessibility focusable nodes in an array, and calculate up/down based on x and y positions.

Upvotes: 3

Related Questions