Search code examples
androidandroid-recyclerviewaccessibilitytalkback

Android iterate RecycleView's hidden items with TalkBack


I have a recycleview which has more than 10 items inside. Because it has more than 10 items, it shows only 4 items at one time. Problem comes with TalkBack, i want to iterate in list with drag left/right actions but after 4. item focus goes on another view components on layout. How can i iterate all items of recycleview with Talkback?

Edit: I use my own accessibility delegate like this:

mRecyclerView.setAccessibilityDelegate(mAccessibilityDelegate);


public class AccessibilityDelegate extends View.AccessibilityDelegate {

private Assistant mAssistant;

public AccessibilityDelegate(Assistant assistant)
{
    mAssistant = assistant;
}

@Override
public void sendAccessibilityEvent(View host, int eventType) {
    if(!mAssistant.isSpeaking() && mAssistant.isRecognizerAvailable())
    {
        super.sendAccessibilityEvent(host, eventType);
    }
}

@Override
public boolean performAccessibilityAction(View host, int action, Bundle args) {
    if(!mAssistant.isSpeaking() && mAssistant.isRecognizerAvailable())
    {
        return super.performAccessibilityAction(host, action, args);
    }

    return false;
}

@Override
public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event) {
    super.sendAccessibilityEventUnchecked(host, event);
}

@Override
public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
    return super.dispatchPopulateAccessibilityEvent(host, event);
}

@Override
public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
    super.onPopulateAccessibilityEvent(host, event);
}

@Override
public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(host, event);
}

@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(host, info);
}

@Override
public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, AccessibilityEvent event) {
    return super.onRequestSendAccessibilityEvent(host, child, event);
}

@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider(View host) {
    return super.getAccessibilityNodeProvider(host);
}

}


Solution

  • After a few trials i found the problem.

    To override RecycleView's accessibility features extend RecyclerViewAccessibilityDelegate.

        //mRecyclerView.setAccessibilityDelegate(mAccessibilityDelegate);
        RVAccessibilityDelegate rvAccessibilityDelegate = new RVAccessibilityDelegate(mRecyclerView, mAssistant);
        mRecyclerView.setAccessibilityDelegateCompat(rvAccessibilityDelegate);
    

    In addition if you want to disable announces like "showing item 1 of 6" simply comment out super.sendAccessibilityEventUnchecked(host, event)

    public class RVAccessibilityDelegate extends RecyclerViewAccessibilityDelegate {
    
    private Assistant mAssistant;
    
    public RVAccessibilityDelegate(RecyclerView recyclerView, Assistant assistant) {
        super(recyclerView);
        mAssistant = assistant;
    }
    
    @Override
    public boolean performAccessibilityAction(View host, int action, Bundle args) {
        if(!mAssistant.isSpeaking() && mAssistant.isRecognizerAvailable())
        {
            return super.performAccessibilityAction(host, action, args);
        }
    
        return false;
    }
    
    @Override
    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
        super.onInitializeAccessibilityNodeInfo(host, info);
    }
    
    @Override
    public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
        super.onInitializeAccessibilityEvent(host, event);
    }
    
    @Override
    public void sendAccessibilityEvent(View host, int eventType) {
        if(!mAssistant.isSpeaking() && mAssistant.isRecognizerAvailable())
        {
            super.sendAccessibilityEvent(host, eventType);
        }
    }
    
    @Override
    public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event) {
        //super.sendAccessibilityEventUnchecked(host, event);
    }
    
    @Override
    public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
        return super.dispatchPopulateAccessibilityEvent(host, event);
    }
    
    @Override
    public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
        super.onPopulateAccessibilityEvent(host, event);
    }
    
    @Override
    public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, AccessibilityEvent event) {
        return super.onRequestSendAccessibilityEvent(host, child, event);
    }
    
    @Override
    public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View host) {
        return super.getAccessibilityNodeProvider(host);
    }
    

    }