Android RecyclerView Background Behavior (GridLayoutManager)

I have a RecyclerView with a GridLayoutManager with two columns per row. Because development is for Android TV, so I need to focus on navigation.

enter image description here

This is normal if I use the down key to jump to any visible items. For example, Point 1 → Point 3 → Point 5 → Point 7 (Only partially visible.). But when I press the key again, the focus will move to point 10 instead of 9.

enter image description here

My grid adapter:

public class GridAdapter extends RecyclerView.Adapter<GridAdapter.ViewHolder> { private ArrayList<String> mDataset; public GridAdapter(ArrayList<String> myDataset) { mDataset = myDataset; } @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.grid_item, viewGroup, false); ViewHolder vh = new ViewHolder(v); return vh; } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.txtTitle.setText(mDataset.get(position)); } @Override public int getItemCount() { return mDataset.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { public TextView txtTitle; public ViewHolder(View v) { super(v); txtTitle = (TextView) v.findViewById(R.id.title); } } } 

Any idea how to solve this problem? Thanks.

+6
source share
2 answers

Check out this related post and Vganin answer to solve your problem.

I reported this error for the AOSP tracker: issue 190526

As I can see from the source, the problem is that the GridLayoutManager uses the LinearLayoutManager - the onFocusSearchFailed () implementation, which when the focus approaches the inner border of the RecyclerView. The LinearLayoutManager implementation offers only the first / last (depends on the scroll direction). Consequently, focus moves to the first / last element of a new line.

My workaround for this problem.

+1
source

I realized that this is the answer. It will not allow you to scroll if a new line is not pumped (so that it will wait for a new line to be pumped.), But usually it takes less than 50-100 ms. Therefore, we agreed that the behavior is acceptable.

Just run onFocusSearchFailed to return null. Here is an example.

/ ** * Created by sylversphere 15-04-22. * / Public class DelayedNaviGridLayoutManager extends GridLayoutManager {

 private final Context context; public SomeGridLayoutManager(Context context, int spanCount) { super(context, spanCount); this.context = context; } public SomeGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) { super(context, spanCount, orientation, reverseLayout); this.context = context; } @Override public View onFocusSearchFailed(View focused, int focusDirection, RecyclerView.Recycler recycler, RecyclerView.State state) { return null; }} 
0
source

Source: https://habr.com/ru/post/981429/


All Articles