touch (a bit more)

本文详细解析了Android中触摸事件的传递机制,包括view.ontouch、father.onintercept及motionevent的工作原理,阐述了不同返回值对后续事件的影响。

-------------------------------------------------view.ontouch
当view.ontouch返回false时,

后续事件(move和up事件)将不再被传递进来(view对后续事件不感兴趣)。事件(如:down) 将传递给帮手(如:father.ontouch)

注意:若ontouch在消费了 某一个后续事件(如:move)后,又返回false,则,后续事件 将继续被传递进来(忽略 false(不感兴趣))

当view.ontouch返回true时,

后续事件(move和up事件)将被传递进来(view对后续事件感兴趣)。事件(如:down) 将不传递给帮手


-------------------------------------------------father.onintercept, father.ontouch, child.ontouch
当father.onintercept返回false时,

拦截后放行,拦截的事件(如:down) 将传递给 child.ontouch

注意:是的,拦截的事件是一定会传给child.ontouch,但是,你要检验一下,该事件的type。

例子1:你为 listview的itemview 设置ontouchlistener。当你在上下滑动listview的时候,恭喜你,你的itemview的ontouch被调用,恩,down事件已经被传递进来了,恩,若干的move事件被传递进来了,但是,你看到:cancel事件被传递进来。随后,listview.ontouch接管了后续的事件(无论,其返回的是true还是false,为什么:参见:当view.ontouch返回false时)(这也是为什么:你看到了list在上下滚动,而itemview被通知:你看上去消耗完了所有的事件)

又怎么样:当你要为 左右滑动itemview 来设置 特殊的响应(如:删除一个item,或者,构造缩进效果),你将会特别的在意:事件到底该如何传递,而又到哪里被消耗完毕,错误的传递将使 整个设计效果 奇形怪状。

例子2:设:father是listview,当前的事件是move,事件传给了father.onintercept。在它返回false之前,你adapter.notifiydatasetchanged,那么,恭喜你,事件将被传递给itemview.ontouch,但是类型是cancel

如果child.ontouch返回false,

后续事件(move和up事件) 将不再传递给 father.onintercept(因为:child已经对后续事件不感兴趣,则,不用再考虑 拦截放行)

如果child.ontouch返回true,

后续事件 将传递给 father.onintercept(因为:child对后续事件感兴趣,仍然要考虑 拦截放行)


当father.onintercept返回true时,

拦截后不放行,拦截的事件 将传递给帮手(father.ontouch)。若事件

类型为down,则不传递给child.ontouch

类型为move,则传递给child.ontouch,且,类型变为cancel

后续事件 将不再传递给 father.onintercept(因为:child无法对后续事件感兴趣,则,不用再考虑 拦截放行)


-------------------------------------------------motionevent

值得说的,如下:

1. getX vs getRawX(同理,对于Y)

getX:touch点 相对于 自身view的父view的 x坐标

getRawX:touch点 相对于 屏幕左顶点的 x坐标

2. getX(同理,对于Y)

getX得到的x坐标,永远都是针对于 自身view的父view(恩,我们又强调了一遍)

也即是:father.onintercepttouchevent(motionevent ev)中,ev.getX得到的是:针对于 father的父view 的x值

什么?:是的,的确拦截了child的motionevent,但是,参数可是传递到father的方法中(onintercepttouchevent)

同理,如果child.ontouchevent返回false,motionevent会再被传递到father.ontouchevent,是的,ev.getX得到的是:针对于 father的父view 的x值

3. motionevent可靠吗

你如果syso一个motionevent,那么将展示它的所有参数

恩,还很体贴,但是,它为什么不是这样:MotionEvent@xxxxxxxx:你可以充分怀疑:运行时的motionevent,永远都只有一个

你可以做实验,将一个motionevent保存,然后,再打印,看看它的参数,还和之前的一样吗?恩,做了实验,一样,那么,handler.postrunnable(syso(motionevent))呢(请确保,你在使用主线程上的handler的队列)?:结果肯定会让你傻眼:x,y的值 实际上是 rawx, rawy。什么?为什么会是这样?:你可以怀疑,除了child/father外,系统在某个地方还在处理motionevent,而motionevent在那个地方 被改变了

so,又怎么样:让我们回想一下:motionevent被怀疑 只有一个对象,且它时时刻刻都在被改变,那么,请不要在你的程序的某个地方保存motionevent,并在某个时刻,调用getX来获得数值

so...:没有了




vdev virtio-input QAVF2.0User's GuideArchitectureConfigurationDeveloper Updated: October 28, 2024 Create an interface for input devices Synopsis vdev virtio-input [display display_id] [force_dev_presence enabled] [global_alpha number] [loc addr intr guest_intr] [offset x_offset,y_offset] [options [+|-]bitmask] [pipeline number] [protocol b] [sched priority] [size x_dimension,y_dimension] [window window_id] [zorder zorder] screen input_type Options display display_id Create an internal transparent window on the specified display to catch all input events from this window and forward them to the guest. This option is ignored if window is defined, because an external window is used in this case. If you don't provide display or window, by default, an internal window on the default display is created. force_dev_presence enabled Specify true if it's necessary to initialize the front end when no physical device is present. If not specified, the default value is false. Currently, this is supported only by the keyboard device. global_alpha number Specify the global alpha (SCREEN_PROPERTY_GLOBAL_ALPHA) for the internal transparent window. This option is ignored if the window option is defined, because an external window is used in this case. intr guest_intr Set the guest interrupt for this virtual device; include this option only if you also include the loc option. The guest_intr argument consists of two colon-separated components: the identifier of the name of the guest device Programmable Interrupt Controller (PIC) the input line that is asserted when the interrupting device wishes to raise an interrupt For example: gic:43 For more information on setting guest interrupts, see the section on “Configuring guests” in the QNX Hypervisor User's Guide. loc addr Set the device space address to addr. The addr argument is typically specified in hexadecimal. If you include this option, the vdev presents itself to the guest as a memory-mapped I/O (MMIO) device at the location specified by addr. Otherwise, the vdev presents itself as a PCI device. You must use this option with the intr option. offset x_offset,y_offset Adjust the x and y coordinates of all events by x_offset and y_offset, respectively. Both arguments are specified in pixels. The guest will see the events at the adjusted coordinates (x+x_offset, y+y_offset). In most cases, you don't need to use this option. It can be useful, however, if the display coordinates of the guest's window are offset from those of the hardware display. options [+|-]bitmask Apply the specified bitmask of options. The optional prefixes, + and -, add or clear the bits in the default bitmask. For instance, if you specify options +0x80, this sets bit 7 (VI_DEV_SENSITIVITY_CONTINUE) if it's not already set. Similarly, if you specify options -0x80, this unsets bit 7 if it's not already unset. If neither prefix is used (e.g., options 0x80), then options would be set to the bitmask (0x80). By default, options is set to 0x12. The rest of the bits are set according to the device. For instance, if the virtio-input vdev presents itself as a mouse (see the screen option), it sets the VI_DEV_POINTER_AS_MOUSE bit when it receives a SCREEN_EVENT_POINTER event. In most cases, you don't need to use the options option. Option Bitmask VI_DEV_EVSYN_MULTIPLE 0x0001 VI_DEV_EVSYN_ALWAYS 0x0002 VI_DEV_POINTER_AS_MOUSE 0x0004 VI_DEV_POINTER_HAS_WHEEL 0x0008 VI_DEV_0FILL (where 0 is zero) 0x0010 VI_DEV_TOUCH_ST 0x0020 VI_DEV_TOUCH_MT 0x0040 VI_DEV_SENSITIVITY_CONTINUE 0x0080 VI_DEV_ALL_OPTIONS 0x00ff pipeline number Specify the pipeline (SCREEN_PROPERTY_PIPELINE) for the internal transparent window. This option is ignored if the window option is defined, because an external window is used in this case. protocol b Change the protocol from type A to type B. The default protocol is type A. This option makes the vdev use the part of the multi-touch (MT) protocol that supports type B devices, which are those devices capable of tracking identifiable contacts. In this case, the protocol describes how to send updates for individual contacts via event slots. For more information, see https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt. Earlier Android versions up to version 11 do not by default support type B devices. To support these devices in earlier versions, you must apply the following kernel patch: https://github.com/torvalds/linux/commit/16c10bede8b3d8594279752bf53153491f3f944f. For later Android versions, this patch is not needed. sched priority Set the priority of the pulses that the VM generates to indicate that new input is available. The default is 10. In most cases, you can omit this option. screen input_type Set the device input type. This option is required. This option tells the virtual device how to present itself to the guest driver. You can specify one of the following values: keyboard Appear as a keyboard device. mouse|pointer Appear as a pointing device with buttons. Specifying mouse tells the virtual device to issue relative coordinates; specifying pointer tells it to issue absolute ones. touch|touchscreen single-touch|multi-touch Appear as a touchscreen device. The touch and touchscreen arguments are aliases; either form tells the virtual device to appear as a touchscreen. If you specify single-touch, the virtual device captures only the first touch point of every multitouch event; if you specify multi-touch, the virtual device captures all the touch points of every multitouch event, up to a maximum of 5 points. If you specify neither of these arguments, the virtual device automatically selects the protocol according to the reported maximum number of touch points. Here's an example of how you can advertise the virtual device as a multitouch device: screen touch screen multi-touch * Capture all input events. The guest will see all supported input devices and receive the events related to them. size x_dimension,y_dimension Advertise the physical size of an absolute-coordinate device (either pointer or touchscreen) as x_dimension and y_dimension. Both arguments are specified in pixels. If you specify the window option, the vdev can automatically determine the physical size of the device and you can omit the size option. Otherwise, you must specify the size option. window window_id Read all input events from the specified external window and forward them to the guest. The window_id argument takes the SCREEN_PROPERTY_ID_STRING of the window that you want to read events from. See the Screen Developer's Guide to learn more about this string and how to retrieve it. If you omit this option, the vdev creates a full-screen input region, reads all input events from the region, and then forwards them to the guest. zorder zorder Specify the z-order (SCREEN_PROPERTY_ZORDER) for the internal transparent window. The default value for this window is 1000. This option is ignored if window is defined, because an external window is used in this case. Description (ARM and x86) The input vdev creates an interface for input devices. It supports USB keyboards, USB mice, and touch input devices. Normally, the vdev appears as a PCI device on x86. But if you specify the loc and intr options, the guest will see the vdev as a memory-mapped I/O (MMIO) device at the location specified by loc. You can specify up to three input devs in a VM configuration, where each vdev presents itself as a different device to the guest. See “Configuration examples” for more information. At least one physical input device must be connected to your host system. The vdev expects to find an input device; if it doesn't, the vdev prevents the qvm process from starting.
08-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值