如何在Android Wear的NestedScrollView中添加Rotary Input支持
为NestedScrollView添加Wear OS Rotary旋转输入支持的完整方案
RecyclerView内置了旋转输入事件的默认处理逻辑,只要申请到焦点即可响应;而NestedScrollView没有默认适配旋转输入,除了申请焦点外,还需要自行实现事件消费逻辑。
1. 配置基础焦点属性
NestedScrollView默认不会主动捕获旋转输入的事件焦点,需要先配置可聚焦属性并主动申请焦点:
- XML布局中为NestedScrollView添加属性:
android:focusable="true" android:focusableInTouchMode="true"
- 页面初始化时主动申请焦点:
binding.mainScroll.requestFocus()
2. 优化旋转输入事件处理逻辑
你当前的实现逻辑核心是正确的,仅需要补充滚动边界校验,避免滚动超出内容范围,优化后的代码如下:
binding.mainScroll.setOnGenericMotionListener { v, ev -> if (ev.action == MotionEvent.ACTION_SCROLL && ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER) ) { val delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) * ViewConfigurationCompat.getScaledVerticalScrollFactor( ViewConfiguration.get(applicationContext), applicationContext ) val scrollDelta = delta.roundToInt() val scrollView = v as NestedScrollView // 计算最大可滚动距离 val maxScrollY = if (scrollView.childCount > 0) { scrollView.getChildAt(0).measuredHeight - scrollView.height } else 0 val targetScrollY = scrollView.scrollY + scrollDelta // 限制滚动范围避免越界 when { targetScrollY < 0 -> scrollView.scrollTo(0, 0) targetScrollY > maxScrollY -> scrollView.scrollTo(0, maxScrollY) else -> scrollView.scrollBy(0, scrollDelta) } true } else { false } }
3. 可选扩展:添加滚动惯性
如果需要实现和系统一致的滚动惯性效果,可以搭配VelocityTracker实现fling逻辑,普通场景下上述代码已经可以满足使用需求。
内容的提问来源于stack exchange,提问作者Sarath Siva
相关产品推荐
相关产品推荐

