多层级手势事件指父子组件嵌套时,父子组件均绑定了手势或事件。在该场景下,手势或者事件的响应受到多个因素的影响,相互之间发生传递和竞争,容易出现预期外的响应。
本章主要介绍了多层级手势事件的默认响应顺序,以及如何通过设置相关属性影响多层级手势事件的响应顺序。
默认多层级手势事件
触摸事件
触摸事件(onTouch事件)是所有手势组成的基础,有Down,Move,Up,Cancel四种。手势均由触摸事件组成,例如,点击为Down+Up,滑动为Down+一系列Move+Up。触摸事件具有最特殊性:
1.监听了onTouch事件的组件,若在手指落下时被触摸则均会收到onTouch事件的回调,被触摸受到触摸热区和触摸控制影响。
2.onTouch事件的回调是闭环的。若一个组件收到了手指Id为0的Down事件,后续也会收到手指Id为0的Move事件和Up事件。
3.onTouch事件的回调是一致的。若一个组件收到了手指Id为0的Down事件未收到手指Id为1的Down事件,则后续只会收到手指Id为0的touch事件,不会收到手指Id为1的后续touch事件。
对于一般的容器组件(例如:Column),父子组件之间onTouch事件能够同时触发,兄弟组件之间onTouch事件根据布局进行触发。
ComponentA() {
ComponentB().onTouch(() => {
})
ComponentC().onTouch(() => {
})
}.onTouch(() => {
})
组件B和组件C作为组件A的子组件,当触摸到组件B或者组件C时,组件A也会被触摸到。onTouch事件允许多个组件同时触发, 因此,当触摸组件B时,会触发组件A和组件B的onTouch回调,不会触发组件C的onTouch回调。 当触摸组件C时,会触发组件A和组件C的onTouch回调,不触发组件B的回调。
特殊的容器组件,如Stack等组件,由于子组件之间存在着堆叠关系,子组件的布局也互相存在遮盖关系。 所以,父子组件之间onTouch事件能够同时触发,兄弟组件之间onTouch事件会存在遮盖关系。
Stack A() {
ComponentB().onTouch(() => {
})
ComponentC().onTouch(() => {
})
}.onTouch(() => {
})
组件B和组件C作为Stack A的子组件,组件C覆盖在组件B上。当触摸到组件B或者组件C时,Stack A也会被触摸到。onTouch事件允许多个组件同时触发,因此,当触摸组件B和组件C的重叠区域时,会触发Stack A和组件C的onTouch回调,不会触发组件B的onTouch回调(组件B被组件C遮盖)。
手势与事件
除了触摸事件(onTouch事件)外的所有手势与事件,均是通过基础手势或者组合手势实现的。例如,拖拽事件是由长按手势和滑动手势组成的一个顺序手势。
在未显示声明的情况下,同一时间,一根手指对应的手势组中只会有一个手势获得成功从而触发所设置的回调。
因此,除非显示声明允许多个手势同时成功,同一时间只会有一个手势响应。
响应优先级遵循以下条件:
1.当父子组件均绑定同一类手势时,子组件优先于父组件触发。
2.当一个组件绑定多个手势时,先达到手势触发条件的手势优先触发。
ComponentA() {
ComponentB().gesture(TapGesture({
count: 1}))
}