android - 区分 OnTouchListener 中的短按(单击)和长按
问题描述
我已经找到了这个答案:在硬件按钮上区分长按和短按 但我对 OnTouchListener 感兴趣。原因是我希望短按和释放(单击)会触发某种行为,但长按(不释放)会触发运动事件,使用户能够用手指拖动小部件。
所以我使用 ACTION_MOVE:
val listener = View.OnTouchListener(function = { view, motionEvent ->
// check if the user gesture upon the view is of moving action
when (motionEvent.action) {
MotionEvent.ACTION_DOWN-> {
// pressed
}
MotionEvent.ACTION_MOVE -> {
view.y = motionEvent.rawY - ((view.height / 2) + 60)
view.x = motionEvent.rawX - view.width / 2
}
MotionEvent.ACTION_UP -> {
// Released
问题是 ACTION_MOVE 会立即触发。是否只有当新闻很长时才可以调用它?我想可能会以某种方式使用时间戳来启用和禁用它,但有没有更简单的解决方案?
解决方案
处理此问题的 Android 方法是使用手势检测器。指南主题检测常见手势讨论了如何执行此操作并提供示例代码。
您希望在触摸侦听器的相对较低级别上进行操作的唯一原因是,如果您要实现的逻辑尚未被库手势检测器之一打包。幸运的是,长按和拖动是已经支持的手势。
如果您仍然想编写自己的逻辑,相应手势检测器的源代码可以为您提供一个很好的起点。但是,我强烈反对这样做,因为逻辑可能非常棘手,需要处理很多边缘情况。
编辑:好的,在阅读了文档之后,我承认它并不像我想象的那么简单。但它也不应该很复杂。从文档中可以清楚地看到问题setIsLongpressEnabled
(强调添加):
设置是否启用长按,如果在用户按下并按住时启用,您会收到一个长按事件而没有进一步的内容。
因此,在检测到长按后,您将不会收到任何滚动回调。您可以按如下方式解决此问题。使用手势检测器的常用方法是编写您的onTouchEvent
方法,如下所示:
override fun onTouchEvent(event: MotionEvent): Boolean {
return if (mDetector.onTouchEvent(event)) {
true
} else {
super.onTouchEvent(event)
}
}
您可以将其更改为如下所示:
var isLongPress = false
override fun onTouchEvent(event: MotionEvent): Boolean {
if (mDetector.onTouchEvent(event)) {
val action = MotionEventCompat.getActionMasked(event)
if (isLongPress && action == MotionEvent.ACTION_MOVE) {
// process the drag
}
return true
}
return super.onTouchEvent(event)
}
然后在onLongPress
回调中,捕获事件坐标并设置isLongPress
. isLongPress
您可以在onDown
回调中清除。然后,您应该忽略任何回调,onScroll
因为根据定义,它们将在没有长按的情况下发生。
推荐阅读
- asp.net-core - Linux 中的中性和 Blazor
- r - R 在列表列工作流程中使用 dplyr::select()
- python - Pandas 根据条件组合连续行
- ios - 如何将 API 数据传递给表格视图单元格
- image-processing - 在 Julia 中并行加载图像
- javascript - 如何在 React Navbar 中显示变量?
- php - 如何在 WooCommerce 的特定位置添加自定义结帐字段
- c++ - 如何使用 C++/WinRT + WinUI 3 以编程方式设置 TextBlock 属性
- django - Django中的条件分页数
- gevent - 如何使 grpc 猴子补丁代码仅打开 v4 套接字。它默认打开一个 v6 套接字