先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新HarmonyOS鸿蒙全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注鸿蒙)
正文
3.在GestureBinding和RendererBinding中进行hitTest
_handlePointerEventImmediately
方法被handlePointerEvent
(上面那个家伙)调用。 这个方法是个重量级的家伙。
void _handlePointerEventImmediately(PointerEvent event) {
HitTestResult? hitTestResult;
if (event is PointerDownEvent || event is PointerSignalEvent || event is PointerHoverEvent) {
//省略…
hitTestResult = HitTestResult();
hitTest(hitTestResult, event.position); //看这里!!!
//省略…
}
dispatchEvent(event, hitTestResult);
}
}
复制代码
到这里,先缓一缓,也许上面我写的不好看不懂也没关系,你只需要记住一件事,我们已经拿到了类型为PointerEvent
的指针事件的数据event
。
(PointerEvent
有多个子类,PointerDownEvent
,PointerMoveEvent
,PointerUpEvent
等等,对应点击
,移动
,抬起
)
核心内容开始
这里以PointerDownEvent
举例,这个事件为用户点击屏幕后产生的。
为什么用户要点击?我猜他在某种APP内发现了一张涩图
想点进去看看。图片肯定是个RenderObject
(不然你能看到个**),那写代码的怎么知道用户点的是哪张图
呢?
Flutter带Hit
开头的接口帮我们做这件事,和RenderObject
相关的有三个接口。
-
HitTestable
的hitTest
方法,让这个RenderObject
能点,什么是能点?稍后的HitTestResult
就会告诉你。 -
HitTestDispatcher
的dispatchEvent
方法,嗯,能发事件。 -
HitTestTarget
的handleEvent
方法,RenderObject
能被点了,那事件你处理不处理,怎么处理,就是这个方法的内容了。
高能来了
从RenderView
的hitTest
进行递归,跟据点击指针事件event
的position
,调用child
的hitTest
。RenderView
是RenderTree的根,怎么来的可以看看Binding
的相关内容。
这里插一则,GestureBinding
有hitTest
,RendererBinding
也有,从runApp
方法可以看到调用内容,super.hitTest
对应GestureBinding
的hitTest
,截图对应的是RendererBinding
。(不影响阅读后面的内容)
递归调用内容解析
RenderTree从RenderView
开始hitTest
。大多数情况下,我们创建的都是RenderBox
,这个盒模型,有长和宽等大小信息,使用笛卡尔坐标系。有的有单个child
,或者双链表式的children
。面对这多种情形,不同的组件有不同的点击测试
内容。
这里通过Stack
和Container
组件,让大家理解下这个递归过程。
Stack(
children: [
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: (){print(“blue”);},
child: Container(width: 300,height: 300,color:Colors.blue)),
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: (){print(“red”);},
child: Container(width: 150,height: 150,color:Colors.red))
],
),
复制代码
某些乱七八糟的BLOG说设置GestureDetector
的behavior
就能实现点击穿透
,然而点击红色方块控制台只输出red。
这是为什么呢?答案是和hitTest
有关。
Stack
对应的是RenderStack
,是一个双链表
的child
模型(由ContainerRenderObjectMixin
实现)。其hitTest
是RenderBox
的方法,原汁原味。
如果这个Box包含点击点,通过hitTestChildren
先对children
逐个进行hitTest
,前者不中则再通过hitTestSelf
自己进行hitTest
。只要中了,就把自己添加进result
。
result
储存的是所有通过的测试的RenderBox
,这些都会接收到指针事件。
RenderStack
的hitTestChildren
hitTest
过程可以解释为从lastChild
开始,向前进行点击测试,直到有一个child
通过,addWithPaintOffset
的内部会添加进result
,然后返回true
。
为什么从lastChild
开始?因为是栈顶
对应的RenderBox
,这样就保证了上面的盖住了下方的,使得一般情况下的点击无法穿透。
hitTestSelf
默认返回false
,子类可以根据需要重写。(GestureDetector
,RenderPointerListener
,Listener
,RenderBoxWithHitTestBehavior
等有详细的内容,之后的点击穿透会讲)
所以结论是,在HitTestChildren
中,红色方块的RenderBox
被添加进了HitTestResult
中,此时就跳出循环,递归回调,所以蓝色方框得不到指针信息。
hitTest
总结
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注鸿蒙)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
vip204888 (备注鸿蒙)**
[外链图片转存中…(img-PRtQFOK8-1713124762302)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!