Prevent Recyclerview from losing focus

I am developping this android TV app which has one activity containing some buttons. After clicking a button, a RecyclerView (in the same activity) gets populated and automatically focused.

The problem is when navigating with DPAD toward the direction of the buttons, the RecyclerView loses focus to the buttons. I want to prevent this behavior, i.e. prevent the RecyclerView from losing focus to anything else on the activity. Later, the only way to select another button is by clicking the back button, this I can do, no problem.

Here is what I have tried, and did not work:

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/categories_rv"
        android:layout_width="@dimen/categories_list_width"
        android:layout_height="wrap_content"
        android:focusable="true"
        android:nextFocusForward="@id/categories_rv"
        android:nextFocusUp="@id/categories_rv"
        android:nextFocusRight="@id/categories_rv"
        android:nextFocusLeft="@id/categories_rv"
        android:nextFocusDown="@id/categories_rv"
        android:focusableInTouchMode="true" />

And this:

 binding.categoriesRv.setOnFocusChangeListener { v, hasFocus ->
     if (!hasFocus)
        v.requestFocus()
  }

In the second way, the FocusChangeListener never gets called unless I use android:descendantFocusability="blocksDescendants" in the RecyclerView, but this prevents the items of the RecyclerView of being focused.

First of all i worked for 3 years on AndroidTv fighting against the focus management, it is actually pretty simple, the problem is...there is no documentation!

On Android-TV the right way to manage the Dpad navigation is actually to use the focusSearch method. What does this do?

DPad navigation actually means the focus changes between some Views. So who should decide where the focus should go when you press Dpad-Right? The ViewGroup (the parent) containing the Views does!

A little background: when a view does not know who should get the focus it asks the ViewGroup to take the decision. So in most cases when you push DpadRight while in focus on a View, focusSearch is called on its container with direction = FOCUS_RIGHT (FOCUS_END) and so on.

The solution for you is then pretty simple. You have 2 ways: 1. Put the Recyclerview inside a BrowseFrameLayout then you can do the following

BrowseFrameLayout browseFrameLayout = view.findViewById(R.id.recyclerview_container);
RecyclerView recyclerView = view.findViewById(R.id.categories_rv);
theBrowseFrameLayout.setOnFocusSearchListener(new BrowseFrameLayout.OnFocusSearchListener() {
    @Override
    public View onFocusSearch(View focused, int direction) {
        if (recyclerView.hasFocus())
            return focused; // keep focus on recyclerview! DO NOT return recyclerview, but focused, which is a child of the recyclerview
        else
            return null; // someone else will find the next focus
    }
});
  1. You can create a custom view extending any container you are using for your recyclerview and do the same, here is a little more complex example that we use with an UI having a top menu and various fragments under it https://gist.github.com/RedLann/bfaffc06eb0f571234c6e46b697d633b

NOTE: Usually in xml we use on recyclerview android:descendantFocusability="afterDescendants" NOTE: Just so you know when a View gets focused for the first time, there is a method of that view that is called, which is:

protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect)

NOTE: If you use this approach the focus management becomes really easy, each Parent view (ViewGroup/Container) will manage the focus for its direct children, when it doesn't know what to do it can delegate to its own parent viewgroup returning super.focusSearch

android - Prevent Recyclerview from losing focus, First of all i worked for 3 years on AndroidTv fighting against the focus management, it is actually pretty simple, the problem isthere is no� Edittext loses content on scroll in recyclerview. Edittext loses focus in recyclerview; This tutorial will solve all the above problems in this Android RecyclerView with EditText Example. We will use the TextWatcher class to control the changes of the edittext. Check out the output of Android RecyclerView With Edittext tutorial.

No matter what you do if you using recyclerview in android tv app it will lose focus. Only solution is using leanback fragments.

Losing Focus, We found that a RecyclerView would lose its focus when you update A workaround exists to avoid the issue by disabling the item animations: The RecyclerView does not attempt to do this. If you want to select an item, do it yourself. It’s not that much code, but could be tricky to get it right. First create a custom class derived from RecyclerView Adapter which uses a custom ViewHolder. This class will perform two major functions: Select an item when the item is clicked

You can achieve this by implementing key listeners on your controls and recyclerview and manage this thing manually.

Add the below method in your adapter class and define each step which you want to perform on every click. It is working in my app I hope it helps you too.

@Override
public void onAttachedToRecyclerView(final RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
    recyclerView.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            LinearLayoutManager lm = ((LinearLayoutManager) recyclerView.getLayoutManager());

            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
                    //return false or true; // whatever your case is
                } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { 
                  return false;

                } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {

                } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {

                } else if (keyCode == KeyEvent.KEYCODE_ENTER) {

                } else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
                }
            }
            return false;
        }
    });


    recyclerView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {


            } else if (!hasFocus) {

            }
        }
    });
}

Workaround for bug with RecycleView focus scrolling when , Workaround for bug with RecycleView focus scrolling when navigating with d- pad (http://stackoverflow.com/questions/31596801/recyclerview-focus-scrolling)� 2.- For sure, that should work nicely. You might lose a bit in "code symmetry" if you end up with a FooAdapter that only emits, and a parent Activity/Fragment that feeds changes into it. But at the end of the day, there's a lot of valid approaches.

Prevent Recyclerview from losing focus, Prevent Recyclerview from losing focus. 发布于 2020-05-03 05:34:38. I am developping this android TV app which has one activity containing some buttons. trows an Exception, saying that can not cast (any layout params here) to recyclerview.layoutparams. :/ i've tried to use the layout params from the viewitem, but they doesn't have "getViewLayoutPosition()" function :(

RecyclerView items lose focus, Android TV RecyclerView focus interaction, Recycler view works fine with So how can i keep the last item's focus when The RecyclerView uses a layout� Sets the AudioAttributesCompat to be associated with the focus request, and which describe the use case for which focus is requested. AudioFocusRequestCompat.Builder: setFocusGain(int focusGain) Sets the type of focus gain that will be requested. AudioFocusRequestCompat.Builder

RecyclerView solution for losing focus when updating data , RecyclerView solution for losing focus when updating data, Programmer Sought, the This type of writing disables all item animations, and you can just disable� The RecyclerView.ViewHolder class provides us a method called getAdapterPosition which will return the proper position of anything that currently drawn on the RecyclerView.

Comments
  • Unfortunately, this did not work either. Neither FocusChangeListener nor OnKeyListener are not being fired when I press down a button.
  • In xml set android:focusable="false" to the controls which you don't want to get focus, and can you share you code?