2

In my code, I use radio group with radio buttons. I want to be able to check the radio buttons with the help of d-pad/ handset. I'm unable to get the focus of individual radio buttons. I tried to do the following:

radioButton.setFocusable(true); radioButton.setFocusableInTouchMode(true);

My radio group is wrapped in a linear layout. So I also tried linearLayout.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); but nothing has worked for me so far. Any input will be helpful

baburaoS
  • 83
  • 1
  • 6

1 Answers1

0

I was running into this issue as well while coding an application for AndroidTV. It seems that horizontal radio group focus simply does not work with dpad, even when nextFocus{direction} is set on views.

Fortunately, if you are using the leanback library, you can use BrowseFrameLayout.onFocusSearchListener to manage focus yourself by doing the following:

Firstly, make sure your layout and radio group do NOT have focusable or focusableInTouchMode set to true. This will cause the layout/group to receive focus instead of the individual buttons.

Wrap your radio group in a BrowseFrameLayout instead of linear layout:

<android.support.v17.leanback.widget.BrowseFrameLayout
        android:id="@+id/browse_frame_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <RadioGroup
        android:id="@+id/radio_group"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/first_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="First Button Text" />

        <RadioButton
            android:id="@+id/second_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Second Button Text" />

    </RadioGroup>
</android.support.v17.leanback.widget.BrowseFrameLayout>

Then in your fragment or activity code, add the following:

BrowseFrameLayout.OnFocusSearchListener onFocusSearchListener =
            new BrowseFrameLayout.OnFocusSearchListener() {

                @Override
                public View onFocusSearch(View focused, int direction) {
                    if (focused.getId() == R.id.first_button && direction == View.FOCUS_RIGHT) {
                        return findViewById(R.id.second_button);
                    } else if (focused.getId() == R.id.second_button && direction == View.FOCUS_LEFT) {
                        return findViewById(R.id.first_button);
                    } else if (focused.getId() == R.id.first_button && direction == View.FOCUS_LEFT) {
                        // return null to allow for default focus transition
                        return null;
                    } else {
                        // return focused to avoid focus change
                        return focused;
                    }
                }
            };
    ((BrowseFrameLayout) findViewById(R.id.browse_frame_layout)).setOnFocusSearchListener(onFocusSearchListener);

That's it! As mentioned in the comments in the sample snippet, returning null will allow for the system to handle default focus transition, and returning focused will block focus change (helpful for up/down clicks on horizontal radio group for example). Returning any other view will focus that view.

This code can be adjusted for any number/type of views in any direction, so while it can be annoying to implement, it is very useful.

This helped me after a lot of frustration, so I hope it helps you!

Brian Acker
  • 323
  • 3
  • 10