背景
小需求,列表中末尾item的焦点转移,定向到新的rv的item中。
默认效果
当2个rv横向并排的时候,末尾的item有焦点,当你按下的时候,他会聚焦到下一个rv的y方向的最近那个item中。看图。
现在需求是末尾按下:切换到第二个rv的第一个item中去。
最原始的方式实现
1:我怎么知道我在最后一个item上面?这个可以根据适配器中的position判断 2:监听末尾的item的按键事件,是否按下
这是监听部分,监听了之后才有下一个rv的聚焦。 适配器
protected void convert(BaseViewHolder helper, String item) {
Button textView = helper.getView(R.id.tv_name);
textView.setText(item);
textView.setTextColor(ContextCompat.getColor(getContext(), R.color.colorWhite));
Log.i(TAG, "convert: 更新title");
final int adapterPosition = helper.getAdapterPosition();
//左边卡主不动,右边卡主不动,不往下跳
if (adapterPosition == 0) {
textView.setNextFocusLeftId(textView.getId());
}
if (adapterPosition == getData().size() - 1) {
textView.setNextFocusRightId(textView.getId());
}
//如果是最后一个item才做焦点的监听
if (itemListener != null && adapterPosition == getData().size() - 1) {
//把当前的控件的焦点监听回传到act
textView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (itemListener != null) {
//往外通知监听焦点
itemListener.onHasFocus(v, adapterPosition, hasFocus);
}
}
});
}
}
通过setOnFocusChangeListener接口可以监听到当前view的点击(就是遥控器的方向键和其他键),这里是是否有焦点。
看处理部分:
//监听最后一个item的按键,切换到下一个rv的第一个元素
textAdapter.setOnListener(new ItemListener() {
@Override
public void onHasFocus(View v, int position, boolean hasFocus) {
if (hasFocus) {
handlerKeyListener(v, position);
}
}
});
private void handlerKeyListener(View v, final int position) {
v.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_DOWN:
if (event.getAction() == KeyEvent.ACTION_DOWN) {
//必须滑动出来,让view可见
rv02.smoothScrollToPosition(0);
//rv02.scrollToPosition(0);
//其中2种方法,可能有时机问题,比如需要滚动rv才能看到目标,这个地方空指针了
//rv02.getLayoutManager().findViewByPosition(0).requestFocus();
//rv02.getChildAt(0).requestFocus();
```//其中一种方法,需要聚焦的item的position
textAdapter2.setPosition(0);
textAdapter2.notifyItemChanged(0);
}
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
//右键也可以处理
//rv02.smoothScrollToPosition(0);
//textAdapter2.setPosition(0);
//textAdapter2.notifyItemChanged(0);
break;
}
return false;
}
});
}
如何给rv的某个item聚焦?
聚焦前,需可见,我们需要先移动到需要聚焦的view上面scrollToPosition或者smoothScrollToPosition都可以。移动之后
//其中一种方法,需要聚焦的item的position,告知适配器需要主动聚焦的位置,然后更新他
textAdapter2.setPosition(0);
textAdapter2.notifyItemChanged(0);
或者
/其中2种方法,可能有时机问题,比如需要滚动rv才能看到目标,这个地方空指针了
rv02.getLayoutManager().findViewByPosition(0).requestFocus();
rv02.getChildAt(0).requestFocus();
都可以。最后看看效果。
项目地址 https://gitee.com/dong_rong/android-tv-sample