本文只讨论如何解决Android TV应用 RecyclerView 焦点乱跑的问题.
RecyclerView的使用方法,大家可以参考此篇博文:http://blog.csdn.net/lmj623565791/article/details/45059587
使用示例:
public static final int ITEMS_COUNT_ONE_LINE = 6;
mRecyclerView = (RecyclerView) root.findViewById(R.id.rv);
mGridLayoutManager = new FocusGridLayoutManager(getContext(), ITEMS_COUNT_ONE_LINE);
mGridLayoutManager.setOrientation(RecyclerView.VERTICAL);
mRecyclerView.setLayoutManager(mGridLayoutManager);
解决此问题的核心是修改 FocusGridLayoutManager
public class FocusGridLayoutManager extends android.support.v7.widget.GridLayoutManager {
}
在此GridlayoutManager中,重载方法onInterceptFocusSearch
@Override
public View onInterceptFocusSearch(View focused, int direction) {
if (direction == View.FOCUS_DOWN) {
int pos = getPosition(focused);
int nextPos = getNextViewPos(pos, direction);
int size = getChildCount();
int count = getItemCount();
if (size > 0) {
int startIndex = 0;
if (size >= mSpanCount) {
startIndex = size - mSpanCount;
}
View view;
for (int i = startIndex; i < size; i++) {
view = getChildAt(i);
if (view == focused) {
int lastVisibleItemPos = findLastCompletelyVisibleItemPosition();
if (pos > lastVisibleItemPos) { //lastVisibleItemPos==-1 ||
return focused;
} else {
int lastLineStartIndex = 0;
if (count >= mSpanCount) {
lastLineStartIndex = count - mSpanCount;
}
if (pos >= lastLineStartIndex && pos < count) { //最后一排的可见view时,返回当前view
return focused;
}
break;
}
}
}
} else {
return focused;
}
}
return super .onInterceptFocusSearch(focused, direction);
}
最核心的是两个地方
1.if (pos > lastVisibleItemPos) 若当前要显示的位置,大于可见的Item的位置,即此时,有可能焦点会乱跑了,此时,返回当前的View作为下一个要Focus的View.
2.if (pos >= lastLineStartIndex && pos < count) 最后一排的可见view时,返回当前view,避免会加载看不见的view,此时也会乱跑。
至此,解决了乱跑问题。其他类型的LayoutManager也可照此方法解决。