重新加一个window_Flutter 上的一个 Bug 带你了解键盘与路由的另类知识点

事情是这样的,由于近期 Flutter 发布了 1.17 的稳定版,按照“惯例”开始着手把生产项目升级到 1.12.13+hotfix.9 版本,在升级适配完成之后,一个突如其来的 Bug 让我陷入了沉思。

4073e869e4d1341d699e2f14e29641e1.png

如上图所示,可以看到在键盘 B 页面打开后,退回上一个页面 A 时键盘已经收起,但是原先键盘所在的区域在 A 页面变成了空白,而 A 页面内容也被 resize 成了键盘弹出后的大小。

1、Scaffold

针对这个问题,首先想到的 Scaffold resizeToAvoidBottomInset 属性。

在 Flutter 中 Scaffold 默认情况下 resizeToAvoidBottomInsettrue,当 resizeToAvoidBottomInsettrue 时,Scaffold 内部会将 mediaQuery.viewInsets.bottom 参与到 BoxConstraints 的大小计算,也就是键盘弹起时调整了内部的 bottom 位置来迎合键盘。

但是问题发送在 A 界面,这时候键盘已经收起,mediaQuery.viewInsets.bottom 应该更新为 0 ,那为何界面没有产生应有的更新呢?

2、MediaQuery

那么猜测问题可能出现在 MediaQuery 上。

从源码我们得知 MediaQuery 是一个 InheritedWidget,它会往下共享对应的 MediaQueryData,在 MediaQueryData 中保存了各种设备的信息,比如 sizedevicePixelRatiotextScaleFactorviewPadding 以及 viewInsets 等。

viewInsets 是什么的呢?官方的解释是:

“可以被系统显示的区域,通常是和设备的键盘等相关,当键盘弹出时 viewInsets.bottom对应的就是键盘的顶部。”

那上面的 bug 看起来可能就是 ScaffoldviewInsets.bottom 在键盘收起来时没有正常重置。

3、Window

那这里首先我们要知道 MediaQueryviewInsets 是怎么被设置的?

通过分析源码可以知道 MediaQuery MediaQueryData 来源于 WidgetsBinding.instance.window,默认是在 Material

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值