Search code examples
kotlinandroid-fragmentsautofocustalkbackaccessibility

talkback not focusing by default on any view on start of inner fragment


I am using accessibility talkback functionality and I am facing one problem I have one bottom navigation in the parent activity and from the setting tab I am opening another fragment(inner fragment) using .add but the inner fragment view not getting focus by default

I also tried with . replace but it's not focusing by default on fragment creation.

open fragment code

val details = DetailsFragment.newInstance();
getSupportFragmentManager().setupForAccessibility()
getSupportFragmentManager().beginTransaction().add(android.R.id.content, details).commit() 

and I used this extension function to not get focus on the previous fragment from this source

fun FragmentManager.setupForAccessibility() {
    addOnBackStackChangedListener {
        val lastFragmentWithView = fragments.lastOrNull { it.view != null }
        for (fragment in fragments) {
            if (fragment == lastFragmentWithView) {
                fragment.view?.importantForAccessibility =
                        View.IMPORTANT_FOR_ACCESSIBILITY_YES
            } else {
                fragment.view?.importantForAccessibility =
                        View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
            }
        }
    }
}

in normal I show that at the start of the first fragment it's focusing top first Textview and speaking automatic but in the inner fragment it's not focusing by default so what should I do to get focus by default on the first view by default

I already try

android:focusable="true"
android:focusableInTouchMode="true"

and request focus but it's not working

Please suggest me any help would be highly appriciated


Solution

  • I've had the best luck using

    view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)
    

    on the view you want to focus, or maybe

    Handler().postDelayed({
        view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)
    }, someDelayMillis)
    

    to let the system do whatever it does, and then jump in after a moment and force a focus change.

    But this might be considered bad accessibility, if it's interfering with the usual navigation, and that might be why it's so hard to get focus working consistently! It might be better to just announce the new fragment (with something like view.announceForAccessibility("new fragment")) and let the user start navigating from the top. It depends on your app, it's your call

    Also you probably want to use replace for your fragment instead of add, if you add a fragment on top of an old one, TalkBack can get stuck looking at the "invisible" views on the old fragment