TV RecyclerView 滑动后操作保持落焦在左侧第一个View
在 recyclerview 中,想要无论滑动到哪,每次按遥控器落焦,需要落焦在左侧第一个 item 上面,如果不能触屏还好,触屏会导致焦点丢失
根据系统的反馈,如果你滑动了列表,刚好列表的 item 卡在一半的位置,此时系统的落焦规则,不一定会到第一个
之前试过一个效果一般的方案,就是通过 findFirstVisibleItemPosition 等方法,去自动获取可见的第一个下标,勉强可以达到重新落焦的预期
但是显然无法精确,如果想要精准的获取第一个item,这种方式显然不行,只能另辟蹊径
居然要求是左上角第一个,那么可以使用坐标来获取 child view,从而得到左侧第一个 item
internal fun RecyclerView.findChildView(x: Float, y: Float): View? {
layoutManager?.let {
for (i in childCount - 1 downTo 0) {
val child = getChildAt(i)
child?.let { view ->
if (x >= view.left && x <= view.right && y >= view.top && y <= view.bottom) {
return view
}
}
}
}
return null
}
这样你会发现,无论怎么滑动,只要 item 位于左上角,就能精准查找到 item view,然后通过 getChildLayoutPosition(view) 方法获取到在 adapter 中的下标
但是有个问题,假设当前坐标中,没有 item 的情况,此时,可以使用第一种方案 findFirstVisibleItemPosition 来获取
最后通过当前的情况去滚动 recyclerview 到指定位置
/** 重新获取焦点时自动滚动定位 */
fun scrollBy() {
val view = findChildView(x + 100f, y + 100f)
val position = if (view == null) getCurrentFirstIndex() else getChildLayoutPosition(view)
Logger.d("scrollBy position $position view is null ${view == null}")
val firstItem: Int = speedLayoutManager.findFirstVisibleItemPosition()
val lastItem: Int = speedLayoutManager.findLastVisibleItemPosition()
//区分情况
if (position <= firstItem) {
//当要置顶的项在当前显示的第一个项的前面时
speedLayoutManager.smoothScrollToPosition("scrollBy1", this, position)
Logger.d("scrollBy smoothScrollToPosition1")
} else if (position <= lastItem) {
//当要置顶的项已经在屏幕上显示时
val top: Int = getChildAt(position - firstItem).top
smoothScrollBy(0, top)
Logger.d("scrollBy smoothScrollBy")
} else {
//当要置顶的项在当前显示的最后一项的后面时
speedLayoutManager.smoothScrollToPosition("scrollBy2", this, position)
Logger.d("scrollBy smoothScrollToPosition2")
}
AppListKeyDownUtils.setFocus("scrollBy", position)
}
这样在失去焦点后重新获取焦点时,落焦的位置就在左上角第一个了
TV RecyclerView 滑动后操作保持落焦在左侧第一个ViewTV RecyclerView 滑动后操作保持落焦在左侧第一个ViewTV RecyclerView 滑动后操作保持落焦在左侧第一个ViewTV RecyclerView 滑动后操作保持落焦在左侧第一个ViewTV RecyclerView 滑动后操作保持落焦在左侧第一个ViewTV RecyclerView 滑动后操作保持落焦在左侧第一个ViewTV RecyclerView 滑动后操作保持落焦在左侧第一个ViewTV RecyclerView 滑动后操作保持落焦在左侧第一个ViewTV RecyclerView 滑动后操作保持落焦在左侧第一个View