需要覆写LinearLayoutManager中的 onFocusSearchFailed方法,在超出当前屏幕时进行特殊处理,
代码如下:
package com.**********.utils;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
public class FocusFixedLinearLayoutManagerextends extends android.support.v7.widget.LinearLayoutManager {
public FocusFixedLinearLayoutManagerextends(Context context) {
super(context);
}
public FocusFixedLinearLayoutManagerextends(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public FocusFixedLinearLayoutManagerextends(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public View onFocusSearchFailed(View focused, int focusDirection, RecyclerView.Recycler recycler, RecyclerView.State state) {
// Need to be called in order to layout new row/column
View nextFocus = super.onFocusSearchFailed(focused, focusDirection, recycler, state);
if (nextFocus == null) {
return null;
}
/**
* 获取当前焦点的位置
*/
int fromPos = getPosition(getFocusedChild());
/**
* 获取我们希望的下一个焦点的位置
*/
int nextPos = getNextViewPos(fromPos, focusDirection);
return findViewByPosition(nextPos);
}
private int getNextViewPos(int fromPos, int direction) {
int offset = getOffset(direction);
return hitBorder(fromPos, offset) ? fromPos : fromPos + offset;
}
private int getOffset(int direction) {
int spanCount = getSpanCount();
int orientation = getOrientation();
if (orientation == VERTICAL) {
switch (direction) {
case View.FOCUS_DOWN:
return spanCount;
case View.FOCUS_UP:
return -spanCount;
case View.FOCUS_RIGHT:
return 1;
case View.FOCUS_LEFT:
return -1;
}
} else if (orientation == HORIZONTAL) {
switch (direction) {
case View.FOCUS_DOWN:
return 1;
case View.FOCUS_UP:
return -1;
case View.FOCUS_RIGHT:
return spanCount;
case View.FOCUS_LEFT:
return -spanCount;
}
}
return 0;
}
private int getSpanCount() {
return 1;
}
private boolean hitBorder(int from, int offset) {
int spanCount = getSpanCount();
if (Math.abs(offset) == 1) {
int spanIndex = from % spanCount;
int newSpanIndex = spanIndex + offset;
return newSpanIndex < 0 || newSpanIndex >= spanCount;
} else {
int newPos = from + offset;
return newPos < 0 && newPos >= spanCount;
}
}
}