Flutter使用WidgetsBinding.instance,路由滑动模式导致第一帧RenderBox坐标测量错误

158 阅读3分钟

前言

接了个浮层引导的需求,需求很好理解,自己写代码实现也不算复杂,不过网上一搜还是有挺多造好的轮子,于是便选了其中一个 showcaseview,确实挺好用的,接入也简单,自己稍微测试了一遍后就交给一生之敌:测试小伙伴。本以为万事大吉,到点就能提桶跑路,结果测试小伙伴说iOS有的机型显示出来的浮层有偏移。

错误显示.jpg

我:?????都要下班了,这刁民总想害朕。

image.png

该死的iOS.....来自Android开发的怨念 T_T

解决思路

思路一:我写的代码怎么可能有bug,肯定是插件本身计算有问题[手动狗头]

这个位置偏差问题,而且还是个别机型才存在,首先我就认为应该是这个showcaseview插件内部的屏幕适配计算没做好,才导致某些机型出了问题。于是打印了坐标位置,发现确实有问题。

错误的计算.jpg

算出的中间坐标是center(226.3,775),但这个x坐标是错的,因为这部手机的屏幕宽度是390,中间x坐标应该是195才对。

于是将该插件的代码放在了本地,将其代码看了一遍,确实有很多计算屏幕宽高的地方,但代码写的都没问题,比如下方计算,取了width和height,同时考虑了ratio;然后调用WidgetsBinding.instance,在页面渲染好第一帧的时候执行逻辑。那么算出来的坐标应该就能适配所有机型才对。

image.png

image.png

之后我不信邪,也换了一些计算写法,结果也依然会发生偏移。

image.png

如此看来便不是插件的问题了,而且这个插件好评率这么高,应该也不会犯这种错误。

思路二:路由跳转的切换模式问题。

既然不是插件的问题,那要么是自己代码写的有问题,要么就是机型系统配置不一样,导致影响了该插件的坐标计算。

经过排查,终于发现了问题所在:路由跳转的时候,ios是自带了从右往左的滑动动画,而Android跳转的时候基本都是直接显示

由此,思路立刻打开了:

image.png

ios的路由跳转有从右到左的动画,也就是说页面跳转是有时间消耗的,那么在插件在调用WidgetsBinding.instance进行计算第一帧的时候,页面已经渲染完了,但页面动画可能还没执行完,也就是页面切换到中途的时候,WidgetsBinding.instance就进行计算了。那么Y坐标也就必然算的就不对了,因为那个时候的计算的起始位置并不是屏幕最左边,x坐标数值自然就会比实际数值更大了。

于是去掉了滑动动画后,果然就正常了。

正确的计算.jpg

参考

后面在查找资料的时候,发现也有人遇到相同问题,同时图文分析的很详细,各位可以移步看一下。# flutter疑难杂症之记一次RenderBox测量坐标错误