平台
测试平台:
- RK3288 + Android8.1
- RK3588 + Android 12
问题
首先, 这个问题的前提是, 使用的输入设备是**鼠标**, 普通的触摸屏并不会出现这个问题. 大致的流程是APP的UI布局中采用ScrollView作为根容器, 之后添加各类子控件, 在一起准备就绪后, 使用鼠标进行功能测试, 出现无法点击控件触发事件响应.
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
style="@style/settingsItems">
<TextView style="@style/TV"
android:text="XXX"
android:layout_weight="1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BTN"/>
</LinearLayout>
<LinearLayout
style="@style/settingsItems">
<TextView style="@style/TV"
android:text="XXX"
android:layout_weight="1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BTN"/>
</LinearLayout>
<!--可以写多几个-->
</LinearLayout>
</ScrollView>
分析
最先从onInterceptTouchEvent
函数入手, 各个层级的LOG大致分析, 由下往上发现控件BUTTON中根本没有捕获到MotionEvent, 那原因只可能是父控件自己捕获了而不下发. 兜兜转转最终来到了ScrollView.
通过重写onInterceptHoverEvent 判断是否时间已被捕获
@Override
public boolean onInterceptHoverEvent(MotionEvent event) {
boolean b = super.onInterceptHoverEvent(event);
Logger.d(TAG, "onInterceptHoverEvent " + b);
return b;
}
从输出的LOG可以看出来, 当使用鼠标的时候, TRUE 和 FALSE 均有可能出现(在后面排查是才发现这和控件处的位置有关), 当TRUE是, 说明事件由ScrollView处理了, 子控件自然就接收不到事件下发.
顺着onInterceptHoverEvent
往上查:
-
frameworks/base/core/java/android/view/ViewGroup.java
public boolean onInterceptHoverEvent(MotionEvent event) { if (event.isFromSource(InputDevice.SOURCE_MOUSE)) { final int action = event.getAction(); final float x = event.getX(); final float y = event.getY();