I used a RecyclerView with HORIZONTAL direction in my TV development which controlled by a D-pad to navigate the list from the left to right. the last item of the RecyclerView always lost focus when navigating to the right-most of the list.
So how can i keep the last item's focus when navigating to the end of the list?
I dug into the source code of RecyclerView, i found the onInterceptFocusSearch method in the LayoutManager, inner class of RecyclerView.
/**
* This method gives a LayoutManager an opportunity to intercept the initial focus search
* before the default behavior of {@link FocusFinder} is used. If this method returns
* null FocusFinder will attempt to find a focusable child view. If it fails
* then {@link #onFocusSearchFailed(View, int, RecyclerView.Recycler, RecyclerView.State)}
* will be called to give the LayoutManager an opportunity to add new views for items
* that did not have attached views representing them. The LayoutManager should not add
* or remove views from this method.
*
* @param focused The currently focused view
* @param direction One of { @link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
* {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT},
* {@link View#FOCUS_BACKWARD}, {@link View#FOCUS_FORWARD}
* @return A descendant view to focus or null to fall back to default behavior.
* The default implementation returns null.
*/
public View onInterceptFocusSearch(View focused, int direction) {
return null ;
}
which gives a LayoutManager an opportunity to intercept the initial focus search before the default behavior of FocusFinder is used.
So i overrided the onInterceptFocusSearch likes below, and used the CustomGridLayoutManager for my RecylerView, which works like a charming.
public class CustomGridLayoutManager extends android.support.v7.widget.GridLayoutManager {
public CustomGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super (context, attrs, defStyleAttr, defStyleRes);
}
public CustomGridLayoutManager(Context context, int spanCount) {
super (context, spanCount);
}
public CustomGridLayoutManager(Context context, int spanCount, int orientation,
boolean reverseLayout) {
super (context, spanCount, orientation, reverseLayout);
}
@Override
public View onInterceptFocusSearch(View focused, int direction) {
int pos = getPosition(focused);
int count = getItemCount();
int orientation = getOrientation();
**********
do some logic
what i did was return the focused View when the focused view is the last item of RecyclerView.
**********
return super .onInterceptFocusSearch(focused, direction);
}
}