RecyclerView嵌套RecyclerView
或者嵌套了LinearLayout,带上属性android:focusable="true" android:focusableInTouchMode="true"
向上翻页,加载item时出现丢焦点。
原因是此时上面的item还没有加载出来。
解决办法:
自定义LinearLayoutManager重写onFocusSearchFailed()方法,返回要获取焦点的item。
@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;
}
}
}