我在我的 Android 应用程序中传播触摸事件时遇到困难。我有一个 ScrollView,其中包含一个充当项目的 View 。当您点击该项目时,我想处理一个 onclick 事件。这可以通过对项目使用 setOnClickListener 来完成。但我还需要拦截 ScrollView 的 ACTION_UP 和 ACTION_DOWN 事件。我使用 ScrollView 的 setOnTouchListener 来做到这一点。
没有收到 ScrollView 的 ACTION_UP 和 ACTION_DOWN。然后我决定对 setOnClickListener 的项目使用 setOnTouchListener。这改善了事情。当您按下该项目时,该项目的 onTouchListener 确实会为 ACTION_DOWN 调用。退出项目的 onTouchListener 时返回 false。然后调用 ScrollView 的 onTouchListener 并接收到 ACTION_DOWN。事情似乎进展顺利。这确实让我感到困惑,但为什么首先调用项目的 onTouchListener 而不是 ScrollView 的。退出 ScrollView 的 onTouchListener 时返回 false。现在,当我松开手指时,将调用 ScrollView 的 ACTION_UP 并返回 false。
此时我遇到的问题是从未调用项目的 ACTION_UP。我一定已经尝试了在两个 onTouchListener 中返回 true/false 的所有组合,但我无法让 ACTION_UP 工作,或者如果我确实让它工作,那么 scrollview 的 onTouchListener 中的某些东西不再工作。
我还尝试在 ScrollView 的 onTouchHandler 中添加 dispatchTouchEvent,但发现我得到了无休止的递归调用。
有没有办法让 ScrollView 及其子项接收 ACTION_UP/ACTION_DOWN?
最佳答案
要让 ScrollView 中的项目响应 onClick,但也知道用户何时向下或向上点击手指,需要一些棘手的编码。此处的解决方案适用于 API 15+。需要注意的关键是 ScrollView 实际上没有使用 onTouchListener。相反,使用 OnSimpleGestureListener 在项目上检测事件。但是,有趣的是,即使有 onDown 方法,OnSimpleGestureListener 也不存在 onUp 方法(见图)。为了解决onUp,你必须测试onTouchEvent的返回值:
GestureDetector gestureDetector = new GestureDetector(context, new GestureDetectorListItem());
listItem.setOnTouchListener(this.onTouchArticleItem);
private View.OnTouchListener onTouchArticleItem = new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
try
{
boolean state = gestureDetector.onTouchEvent(event);
if ((event.getAction() == android.view.MotionEvent.ACTION_UP) && !state)
{
// Handle up event here.
return true;
}
else if ((event.getAction() == android.view.MotionEvent.ACTION_DOWN) && state)
{
// Handle down event here.
return true;
}
else
return state;
}
catch (Exception ex)
{
Logger.Log(context, ex.getMessage(), Log.ERROR);
return false;
}
}
};
private class GestureDetectorListItem extends GestureDetector.SimpleOnGestureListener
{
public boolean onSingleTapUp(MotionEvent e)
{
return true;
}
public void onLongPress(MotionEvent e)
{
}
public boolean onDoubleTap(MotionEvent e)
{
return false;
}
public boolean onDoubleTapEvent(MotionEvent e)
{
return false;
}
public boolean onSingleTapConfirmed(MotionEvent e)
{
return false;
}
public void onShowPress(MotionEvent e)
{
}
public boolean onDown(MotionEvent e)
{
return true;
}
public boolean onScroll(MotionEvent e1, MotionEvent e2, final float distanceX, float distanceY)
{
return super.onScroll(e1, e2, distanceX, distanceY);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
return super.onFling(e1, e2, velocityX, velocityY);
}
}
我在这个解决方案中看到的唯一问题是 ScrollView 是否有太少的项目无法滚动。如果项目太少并且用户按下 ScrollView 上某处而不是项目,则不会检测到向上/向下事件。这在您的应用程序中是否重要是您必须决定的事情。如果需要,则可能还需要为 ScrollView 包含一个 onTouchListener。
关于android - 在 ScrollView 中传播触摸事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30340095/