- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个自定义 View ,其中我具有触摸事件功能(滑动等)。现在可能会发生这种情况,即在 ScrollableLayout
中使用此自定义 View 。那么问题是,当用户在我的自定义 View 内滑动时,父级 (ScrollableLayout) 也会处理滑动手势,因此它会滚动,但它不应该滚动。
我需要来自 JavaScript 的类似 event.preventDefaults()
的东西。
我覆盖 View#onTouchEvent
并始终返回 true
。我想,当我从 onTouchEvent
返回 true 时,这意味着该事件已被消耗并且没有其他 View 将获得 onTouchEvent,但这是错误的。
谁能帮帮我?
我的 View 很容易测试:
public class PreventingTouchEventView extends View {
public PreventingTouchEventView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.RED);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(200, 200);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return true;
}
}
我将一个示例android项目推送到了github: https://github.com/jjoe64/android-preventing-touch-test
如果您在红色 Canvas 内触摸和滚动,ScrollableLayout 应该不滚动。
最佳答案
要防止触摸该布局,您有多种选择:
1) 设置 OnTouchListener,它总是返回 true。
2) 覆盖 dispatchTouchEvent(MotionEvent event) 总是返回 true
UPD: 好吧,通常你必须设置 OnTouchListener,它总是返回 true,正如我之前所说,以防止其他 View 被调用 onTouch
,但是ScrollView 完全是另一个故事。
首先,我将介绍 dispatchTouchEvent
的工作原理。它开始从 Root View 向其 subview 分派(dispatch)事件,这意味着父 View 的 dispatchTouchEvent
被其 subview 的 BEFORE dispatchTouchEvent
调用。
然后在ViewGroup.dispatchTouchEvent()
里面有一段代码
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
决定是否应该拦截此触摸事件,这意味着如果 intercepted
标志为真,则此 View 将拦截所有后续事件。并在 ScrollView
onInterceptTouchEvent
中实现拦截正在执行垂直滚动的操作。
所以我的第一个想法是将 FLAG_DISALLOW_INTERCEPT
设置为自定义 View 的父级,以禁止拦截事件的机会,但由于 ViewGroup< 中的下一行代码,这个想法失败了
:
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Throw away all previous state when starting a new touch gesture.
// The framework may have dropped the up or cancel event for the previous gesture
// due to an app switch, ANR, or some other state change.
cancelAndClearTouchTargets(ev);
resetTouchState();
}
这意味着在 MotionEvent.ACTION_DOWN
之后所有状态都被清除(FLAG_DISALLOW_INTERCEPT
也被清除)。
所以最终的解决方案很简单
public class PreventingTouchEventView extends View {
public PreventingTouchEventView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.RED);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (getParent() != null && event.getAction() == MotionEvent.ACTION_DOWN) {
getParent().requestDisallowInterceptTouchEvent(true);
}
return super.dispatchTouchEvent(event);
}
}
这会在第一个 MotionEvent.ACTION_DOWN
之后立即引发 FLAG_DISALLOW_INTERCEPT
,这将禁止父级进一步拦截 future 的操作。
但请注意,如果您的 parent 认为在 MotionEvent.ACTION_DOWN
上做了一些疯狂的事情并拦截了此事件,那么您对此无能为力,因为您 parent 的 dispatchTouchEvent
在您的 dispatchTouchEvent
之前被调用。
关于android - 如何防止 TouchEvent 滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17837711/
将 @HostListener 与明确键入为 TouchEvent 的事件参数一起使用,会导致 Firefox 崩溃并显示以下错误消息: ReferenceError: TouchEvent is n
我有一个 WPF 触摸应用程序,它运行得很好,除了一件事:捕获用户第一次触摸元素时触发的事件。 TouchDown 似乎不起作用,至少没有明显的延迟。当用户将手指滑到元素上时,TouchEnter 工
在我的应用程序中,用户可以开始录制,他们触摸的每个按钮都将保存到一个数组中 例如: "[{"time":1835,"elemId":"bass"},{"time":2553,"elemId":"hig
我正在构建一个具有整页水平和垂直滚动功能的小网站。查看 codepen 演示 here.演示有一个错误,“向左”和“向上”按钮无法正常工作。 “向右”和“向下”按钮工作正常。我只是把它们放在一起向您展
我有一个问题,如果我在字段外按下/触摸 fieldChanged()为具有焦点的字段触发事件。 我的 MainScreen 的布局很简单,就像这样: public class myMainScreen
TouchEvent.supported尝试创建TouchEvent以确定触摸支持。这适用于实际的触摸设备,但是在使用Chromium DevTools:“模拟触摸屏”时无济于事。 Chromium确
我有几个关于 ADB 的问题。 我尝试运行以下批处理文件: adb wait-for-devices adb shell sendevent /dev/input/event9 3 53 67 adb
我正在开发一个移动应用程序,并且在各种元素上有很多触摸事件。不幸的是,我无法在我的电脑浏览器上测试我的应用程序,因为它不支持 touchevents。如果我在 PC 上运行(当然是通过检查用户代理),
好的,所以在业余时间创建游戏时,我在尝试围绕以下场景编写代码时完全陷入困境: 我想捕获点击事件 (TouchEvent.ACTION_DOWN),然后以 500 毫秒为间隔,我想检查屏幕是否仍被按下,
已关闭。此问题旨在寻求有关书籍、工具、软件库等的建议。不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以
您好,我正在开发一个应用程序,在该应用程序中,我在 Activity 中使用对话框。对话框将只显示一张图片,当用户触摸图片时,对话框应该关闭,启动对话框的 Activity 应该出现在前面。 对话框没
这应该很简单吧?! 因此,我有一个 Gameobject 作为按钮,我在扩展 SurfaceView 的 GamePanel 上引用它,如下所示: bby = new Buttons(BitmapFa
需要在桌面浏览器上使用移动设备模拟来自动化测试。 如果通过ChromeOptions()启用模拟,则触摸屏的模拟不起作用(按钮响应光标等)。这就是为什么我使用 java.awt.Robot (F12
我在尝试从 BB10 级联 API 获取触摸事件的目标时遇到问题。我有几个容器,一个在另一个下面,每个容器都分配了相同的 Touch 信号和插槽。一切都从 C++ 动态加载。因此,为了捕捉每个触摸事件
我有一个自定义 View ,其中我具有触摸事件功能(滑动等)。现在可能会发生这种情况,即在 ScrollableLayout 中使用此自定义 View 。那么问题是,当用户在我的自定义 View 内滑
我的布局看起来像这样: ViewPager 内部有许多 Fragment,每个 Fragment 都有一个 ListView。 现在我想这样做: 通过向下滚动,ListView 不得滚动。相反,必须转
我想在我的 Android 应用程序任何时候触摸屏幕时接收 TouchEvent。即使我的应用程序不在焦点中。 是否有我可以编写的通用事件监听器或 Intent 过滤器来实现此目的? 目标是编写系统范
我有一个 Angular 8 项目,我想在其中处理触摸事件。示例处理程序: @HostListener('touchend', ['$event']) onTouchend(event: TouchE
我正在为一个函数写一个测试 MyFuntion并调用另一个函数sendTouchEvent实例化一个TouchEvent。 function sendTouchEvent(element, event
我正在考虑一个易于使用的 android 可用性测试工具,它将允许用户在应用程序测试期间记录和记录相关信息。作为第一个结果,我希望每次用户与触摸屏交互时截取屏幕截图,其中显示了触摸事件的位置、持续时间
我是一名优秀的程序员,十分优秀!