需求背景 : Android TV开发视频列表最后一行未满时,如果当前焦点在倒数第二行,下面为空,需要特殊处理将KEYCODE_DPAD_DOWN事件,移动焦点至最后一行
处理逻辑 : OnChildViewHolderSelectedListener监听中,记录位置,在setOnKeyListener中处理KEYCODE_DPAD_DOWN事件跳转逻辑。
具体逻辑参考如下代码 :
public class CustomVerticalGridView extends VerticalGridView {
private int columns;
private int itemCount;
private static final String TAG = "CustomVerticalGridView";
/**
* 倒数第二行下方没有item的时候,
* 按KEYCODE_DPAD_DOWN时,最后一行第一个item获取焦点
*/
private final OnChildViewHolderSelectedListener mListener = new OnChildViewHolderSelectedListener() {
@Override
public void onChildViewHolderSelected(RecyclerView parent, ViewHolder child, int position, int subPosition) {
super.onChildViewHolderSelected(parent, child, position, subPosition);
itemCount = Objects.requireNonNull(getAdapter()).getItemCount();
Log.d(TAG, "position=======" + position);
Log.d(TAG, "itemCount======" + itemCount);
int lastRowNumber = itemCount % columns;
int rowNumber = itemCount / columns;
//用于判断当前位置是倒数第二行,且下方Item为空
if ((lastRowNumber > 0) && ((position + 1) <= (itemCount - lastRowNumber)) &&
((position + 1) > (rowNumber * columns - (columns - lastRowNumber)))) {
child.itemView.setOnKeyListener((v, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN && event.getAction() == KeyEvent.ACTION_DOWN) {
//焦点移动至最后一行第一个
//此处逻辑可根据具体项目要求修改
scrollToPosition(rowNumber * columns);
}
return false;
});
}
}
};
public CustomVerticalGridView(Context context) {
super(context);
setOnChildViewHolderSelectedListener(mListener);
}
public CustomVerticalGridView(Context context, AttributeSet attrs) {
super(context, attrs);
setOnChildViewHolderSelectedListener(mListener);
}
public CustomVerticalGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setOnChildViewHolderSelectedListener(mListener);
}
@Override
public void setNumColumns(int numColumns) {
super.setNumColumns(numColumns);
Log.i(TAG, "setNumColumns=====" + numColumns);
columns = numColumns;
}
}