Flutter笔记:Flutter的WidgetsBinding.instance的window属性
作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263
邮箱 :291148484@163.com
本文地址:https://blog.csdn.net/qq_28550263/article/details/134128693
目 录
1. 关于 WidgetsBinding
很多初学者是不会接触和用到 WidgetsBinding.instance的,本文介绍的知识点是 WidgetsBinding.instance 的一个小部分。因此,先对 WidgetsBinding.instance 进行大概的介绍。
WidgetsBinding.instance 是Flutter中的一个核心类的实例,用于管理应用程序的事件循环和处理各种事件,例如布局、绘制、手势和系统事件。它是 WidgetsBinding 类的一个单例实例,通过它可以访问应用程序的根 WidgetsBinding 对象。
WidgetsBinding 类是 Flutter 框架的一部分,它包含了以下常用的功能和应用:
-
事件循环管理:WidgetsBinding负责管理Flutter应用程序的事件循环,它处理了各种事件的分发和调度。这包括构建(build)事件、布局(layout)事件、绘制(paint)事件等。
-
处理系统事件:WidgetsBinding 可以处理系统级事件,例如按键事件、触摸事件、指针事件等。它允许应用程序响应用户的输入和交互。
-
定时器和帧回调:WidgetsBinding允许你注册定时器和帧回调,以便在未来的时间点执行代码或在下一帧绘制前执行代码。
-
状态管理:WidgetsBinding 管理应用程序的生命周期状态,包括
inactive
、paused
、resumed
和detached
状态。这有助于应用程序在不同状态下进行适当的处理。 -
媒体和屏幕分辨率信息:WidgetsBinding 提供了访问媒体查询(MediaQuery)和屏幕信息的方法,以便根据屏幕属性调整UI。
-
错误处理:WidgetsBinding 还处理了Flutter应用程序中的异常和错误,允许你注册全局错误处理程序。
-
根`BuildContext:WidgetsBinding 提供了根 BuildContext,可以用于构建全局部件。
WidgetsBinding 是整个 Flutter 应用程序事件和生命周期管理的关键。开发者可以通过 WidgetsBinding.instance 来访问它,并注册事件回调,以便在应用程序的各个生命周期阶段执行自定义操作。例如,你可以使用 WidgetsBinding 来注册全局的错误处理程序,管理应用程序的生命周期状态,或执行定时任务。
2. window 属性概述
WidgetsBinding.instance.window是一个全局单例对象,它提供了许多用于获取和控制Flutter应用程序窗口的属性。这些属性主要用于以下方面:
- 物理尺寸(Physical Size);
- 设备像素比(Device Pixel Ratio);
- 平台亮度(Platform Brightness);
- 语言环境(Locale);
- 可访问性特性(Accessibility Features);
- 文本缩放因子(Text Scale Factor);
3. 物理尺寸(Physical Size)
window.physicalSize属性返回一个Size对象,表示窗口的物理尺寸,单位是设备独立像素。
Size size = WidgetsBinding.instance.window.physicalSize;
这个尺寸是实际像素数量,不受设备像素比例影响。
Size size = WidgetsBinding.instance.window.physicalSize;<div id="3-1"></div>## <a href="#3-1"><font color="#037781">3.1 全屏显示</font>如果你需要在应用中创建一个全屏的元素或者背景,你可以使用window.physicalSize来获取屏幕的尺寸,然后设置元素或者背景的尺寸。例如:```dart
Container(width: window.physicalSize.width,height: window.physicalSize.height,color: Colors.red,
)
3.2 与 MediaQuery 对比
需要指出 MediaQuery 和 window.physicalSize 都可以用来获取设备的尺寸信息,但它们的使用场景和方式有所不同。
MediaQuery
MediaQuery 是Flutter的一个 组件,它可以用来获取设备的媒体查询信息,如屏幕尺寸、设备像素比、文本缩放因子等。 MediaQuery 考虑了更多的因素,如设备方向、系统UI(如状态栏和导航栏)等。在大多数情况下,你应该使用 MediaQuery 来获取设备的尺寸信息。
例如,你可以使用 MediaQuery 来获取屏幕的宽度,并根据宽度来调整布局:
double screenWidth = MediaQuery.of(context).size.width;Container(width: screenWidth / 2,height: 100,color: Colors.red,
)
window.physicalSize
window.physicalSize 是一个全局单例对象,它提供了设备的物理尺寸信息。这个尺寸是设备独立的,不受设备像素比的影响。然而,window.physicalSize 没有考虑设备方向和系统UI,所以它提供的尺寸信息可能不准确。
结论
-
window.physicalSize 提供的是设备的物理尺寸,这是一个固定的值,不会因为设备的方向或者系统UI的变化而改变。因此, window.physicalSize 在一些需要获取设备固定尺寸的场景中可能会有用。例如,如果你正在开发一个游戏或者图形密集型的应用,你可能需要直接操作设备的物理像素。在这种情况下, window.physicalSize 可以提供你需要的尺寸信息。
-
另一个可能的使用场景是在处理设备方向变化时。当设备的方向改变时,MediaQuery 的尺寸信息也会改变,但 window.physicalSize 不会。因此,如果你需要在设备方向改变时保持一致的尺寸信息,你可以使用 window.physicalSize。
-
然而,这些场景在大多数应用中都比较少见。
因此在大多数情况下,应该避免直接使用 window.physicalSize,而是使用 MediaQuery 和 Flutter 的布局系统来创建自适应的布局。
4. 设备像素比(Device Pixel Ratio)
window.devicePixelRatio 属性返回的是设备的像素比例,这个比例是物理像素和逻辑像素之间的比例。在高分辨率设备上,这个比例通常大于1。
double ratio = WidgetsBinding.instance.window.devicePixelRatio;
这个属性可以用于在需要精确控制像素级别的渲染或者需要处理设备像素密度差异的场景中。
4.1 处理高分辨率图像
如果你的应用需要显示高分辨率的图像,你可以使用window.devicePixelRatio 来确定需要加载的图像的分辨率。例如,如果设备的像素比例是2.0,你可以加载2x的图像以获得最佳的显示效果。
★例如,假设你有一张图像它有两个版本:一个是 1x的版本,一个是 2x的版本。你可以使用 window.devicePixelRatio 来确定应该加载哪个版本的图像。代码实现就像下面这样写:
/// 获取设备的像素比率,以确定屏幕的像素密度。
double devicePixelRatio = WidgetsBinding.instance.window.devicePixelRatio;if (devicePixelRatio >= 2.0) {// 如果像素比率大于等于2.0,加载图像的2x版本Image.asset('images/my_image@2x.png');
} else {// 如果像素比率小于2.0,加载图像的1x版本Image.asset('images/my_image.png');
}
上面的代码中,我们首先获取设备的像素比例。然后,如果像素比例大于或等于2.0,我们加载2x版本的图像;否则,我们加载1x版本的图像。
这样,我们可以确保在高分辨率的设备上显示高分辨率的图像,而在低分辨率的设备上显示低分辨率的图像,从而获得最佳的显示效果。
4.2 自定义绘制
在使用 CustomPaint 进行自定义绘制时,你可能需要使用 window.devicePixelRatio 来确保你的绘制在所有设备上看起来都一样。比如可以使用 window.devicePixelRatio 来调整线条的宽度或者圆角的半径。
假设你正在绘制一个有圆角的矩形,你希望圆角的半径在所有设备上看起来都一样。你可以使用 window.devicePixelRatio 来调整圆角的半径。
/// 自定义绘制器类,用于绘制一个红色的圆角矩形。
class MyPainter extends CustomPainter {void paint(Canvas canvas, Size size) {// 计算设备像素比,以确保在不同设备上获得一致的渲染效果。double devicePixelRatio = WidgetsBinding.instance.window.devicePixelRatio;double radius = 10 * devicePixelRatio;// 创建一个 Paint 对象,用于定义绘制属性。var paint = Paint()..color = Colors.red // 设置绘制颜色为红色。..style = PaintingStyle.fill; // 设置绘制样式为填充。// 创建一个覆盖整个画布尺寸的矩形。var rect = Rect.fromLTWH(0, 0, size.width, size.height);var rrect = RRect.fromRectAndRadius(rect, Radius.circular(radius));// 使用定义的 Paint 对象在画布上绘制一个圆角矩形。canvas.drawRRect(rrect, paint);} bool shouldRepaint(CustomPainter oldDelegate) {// 我们不需要重绘,因为绘制是静态的。return false;}
}
然后这样使用:
CustomPaint(painter: MyPainter(),
)
5. 平台亮度(Platform Brightness)
5.1 描述
window.platformBrightness 属性返回当前平台的亮度模式,这个模式通常由用户在设备的设置中选择。这个属性可以用来判断当前是否使用 暗黑模式。
5.2 案例
下面的例子展示了如何使用 window.platformBrightness 来判断当前是否使用暗黑模式,并根据此来设置应用的主题:
// main.dart/// 获取当前设备窗口的亮度模式,用于确定应用程序的主题模式。
Brightness brightness = WidgetsBinding.instance.window.platformBrightness;ThemeData theme;
if (brightness == Brightness.dark) {// 如果亮度模式为暗模式,使用暗色主题theme = ThemeData.dark();
} else {// 如果亮度模式为亮模式,使用亮色主题theme = ThemeData.light();
}MaterialApp(theme: theme, // 将主题应用于应用程序home: MyHomePage(), // 设置应用程序的主页为 MyHomePage
);
这段代码我们首先获取当前平台的亮度模式:
- 如果亮度模式是Brightness.dark,我们使用暗黑主题;
- 否则,我们使用明亮主题。
通过这样,我们可以确保我们的应用的主题与用户在设备设置中选择的亮度模式一致。
6.语言环境(Locale)
6.1 描述
window.locales 属性返回一个包含当前设备所有语言环境的列表。第一个语言环境是当前设备的主要语言环境。
6.2 案例
下面用一个小例子展示如何使用 window.locales 来获取当前设备的主要语言环境,并根据此来设置应用的本地化设置:
/// 获取应用程序窗口支持的所有语言区域信息。
List<Locale> locales = WidgetsBinding.instance.window.locales;/// 从支持的语言区域列表中选择主要的语言区域。
Locale primaryLocale = locales.first;MaterialApp(locale: primaryLocale, // 设置应用程序的主要语言区域localizationsDelegates: [// 添加您的本地化代理(localizations delegates)在这里],supportedLocales: [// 添加您支持的语言区域列表在这里],home: MyHomePage(), // 设置应用程序的主页为 MyHomePage
);
这段代码中,我们首先获取当前设备的所有语言环境,然后取出第一个语言环境作为主要语言环境。然后,我们在MaterialApp中设置locale属性为主要语言环境。
这样,我们可以确保我们的应用的本地化设置与用户在设备设置中选择的语言环境一致。
需要指出的是,在实际开发中,可能需要根据语言环境来调整更多的文本和布局。你还需要提供本地化委托 (localizationsDelegates )和支持的语言环境列表(supportedLocales),以便Flutter可以正确地加载和显示本地化的文本。就像这样:
import 'package:flutter_localizations/flutter_localizations.dart';const MaterialApp(localizationsDelegates: <LocalizationsDelegate<Object>>[// ... 应用程序特定的本地化代理(localizations delegates)在这里GlobalMaterialLocalizations.delegate,GlobalWidgetsLocalizations.delegate,],supportedLocales: <Locale>[Locale('en', 'US'), // 英语Locale('he', 'IL'), // 希伯来语// ... 应用程序支持的其他语言区域],// ...
)
7.可访问性特性(Accessibility Features)
7.1 描述
window.accessibilityFeatures 属性返回一个表示当前设备的可访问性特性的位掩码。这个位掩码可以用来判断当前设备是否启用了某些可访问性特性,如屏幕阅读器、大字体等。
7.2 案例
下面的例子展示如何使用 window.accessibilityFeatures 来判断当前设备是否启用了屏幕阅读器:
/// 获取窗口的辅助功能特性,用于检查设备是否启用了辅助功能。
AccessibilityFeatures accessibilityFeatures = WidgetsBinding.instance.window.accessibilityFeatures;if (accessibilityFeatures.accessibleNavigation) {// 设备启用了屏幕阅读器print('屏幕阅读器已启用');
} else {// 设备未启用屏幕阅读器print('屏幕阅读器未启用');
}
这段代码中,我们首先获取当前设备的可访问性特性。然后,我们检查 accessibleNavigation 是否启用。如果启用,我们打印 Screen reader enabled
否则,我们打印Screen reader disabled
。
这样,我们可以根据用户的可访问性设置来调整我们的应用的行为。例如,如果用户启用了屏幕阅读器,我们可能需要提供更多的文本描述,或者调整我们的布局和导航。
需要指出的是,在实际开发中可能需要处理更多的可访问性特性,如大字体、高对比度等。你还需要确保你的应用遵循可访问性最佳实践,以便所有用户都可以轻松地使用应用。
7.文本缩放因子(Text Scale Factor)
8.1 描述
window.textScaleFactor属性返回用户设置的文本缩放因子。这个因子用于计算字体的实际显示大小。
double scale = WidgetsBinding.instance.window.textScaleFactor;
8.2 案例
下面的例子展示如何使用 window.textScaleFactor 来获取文本缩放因子,并根据此来设置文本的大小:
double textScaleFactor = WidgetsBinding.instance.window.textScaleFactor;Text('Hello, world!',style: TextStyle(fontSize: 20 * textScaleFactor),
);
这段代码中,我们首先获取用户设置的文本缩放因子。然后,我们将文本缩放因子乘以我们想要的字体大小(在这个例子中是20),得到实际的字体大小。然后,我们使用这个字体大小来创建一个 Text 组件。这样,我们可以确保我们的文本的大小与用户在设备设置中选择的文本大小一致。
需要指出的是,Flutter 的 Text 组件默认已经考虑了文本缩放因子,所以你通常不需要手动获取和使用window.textScaleFactor。上面的示例主要是为了演示window.textScaleFactor 的用法。——在实际开发中,你应该让 Flutter 自动处理文本缩放,以确保最佳的可访问性和用户体验。
8.API 迁移信息
注:当前Flutter积极更新,成文时版本为3.13,虽然仍违背删除。但是从 Flutter 3.7.0-32.0.pre 版本之后,window 属性已标记为弃用。通过 View.of(context) 从上下文中查找当前 FlutterView,或者直接咨询 PlatformDispatcher。 以为即将到来的 多窗口支持 做准备。
例如之前的:
Size size = WidgetsBinding.instance.window.physicalSize;
目前可以改用:
double width = View.of(context).display.size.width;
这将会在我的另外一期博客专门介绍。
相关文章:

Flutter笔记:Flutter的WidgetsBinding.instance的window属性
Flutter笔记 Flutter的WidgetsBinding.instance的window属性 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/det…...

element UI DatePicker 日期选择器 点击时间点可选限制范围前后十五天
<el-date-picker v-model"timeRange" type"datetimerange" align"right" :default-timedefaultTimevalue-format"yyyy-MM-dd HH:mm:dd" range-separator"至" start-placeholder"开始日期"end-placeholder"…...

【自用】vmware workstation建立主机window与虚拟机ubuntu之间的共享文件夹
1.在windows中建立1个文件夹 在vmware中设置为共享文件夹 参考博文: https://zhuanlan.zhihu.com/p/650638983 2.解决: (1)fuse: mountpoint is not empty (2)普通用户也能使用共享目录 参考博文&#x…...

【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A:基于计算机视觉的坑洼道路检测和识别 python 代码解析
【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A:基于计算机视觉的坑洼道路检测和识别 python 代码解析 1 题目 坑洼道路检测和识别是一种计算机视觉任务,旨在通过数字图像(通常是地表坑洼图像)识别出存在坑洼的道路。这…...

Mozilla Firefox 119 现已可供下载
Mozilla Firefox 119 开源网络浏览器现在可以下载了,是时候先看看它的新功能和改进了。 Firefox 119 改进了 Firefox View 功能,现在可以提供更多内容,如最近关闭的标签页和浏览历史,你可以按日期或网站排序,还支持查…...

What is 哈希?
哈希 前言:大一大二就一直听说哈希哈希,但一直都没有真正的概念:What is 哈希?这篇博客就浅浅聊一下作者认知中的哈希。 理解哈希 哈希(Hash)也可以称作散列,实质就是一种映射…...

在Photoshop中如何校正倾斜的图片
在Photoshop中如何校正倾斜的图片呢?今天就教大家如何操作。 将需要操作的图片拉到PS软件中,自动形成项目。 点击上方“滤镜”中的“镜头校正”。 进入“镜头校正”窗口,点击左侧的“拉直工具”。文章源自设计学徒自学网-http://www.sx1c.co…...

Maven第六章:Maven的自定义插件开发
Maven第六章:Maven的自定义插件开发 前言 maven不仅仅只是项目的依赖管理工具,其强大的核心来源自丰富的插件,可以说插件才是maven工具的灵魂。本篇文章将对如何自定义maven插件进行讲解,希望对各位读者有所帮助。 Maven插件开发的基本概念 Maven插件是由Maven构建工具本身…...

springboot 注入配置文件中的集合 List
在使用 springboot 开发时,例如你需要注入一个 url 白名单列表,你可能第一想到的写法是下面这样的: application.yml white.url-list:- /test/show1- /test/show2- /test/show3Slf4j RestController RequestMapping("/test") pub…...

springboot整合redis+lua实现getdel操作保证原子性
原始代码 脚本逻辑先获取redis的值,判断是否等于期望值。 条件成立则删除,不成立则返回0 if redis.call(get, KEYS[1]) ARGV[1] thenreturn redis.call(del, KEYS[1]) end return 0 测试代码 根据上面的逻辑加了测试, 在判断成功后等待5…...

win10系统nodejs的安装npm教程
1.在官网下载nodejs,https://nodejs.org/en 2,双击nodejs的安装包 3,点击 next 4,勾选I accpet the terms in…… 5,第4步点击next进入配置安装路径界面 6,点击next,选中Add to PATH ,旁边…...

C语言assert函数:什么是“assert”函数
我一直在学习 OpenCV 教程,遇到了assert函数;它做什么? assert将终止程序(通常带有引用 assert 语句的消息),如果其参数为 false。它通常在调试过程中使用,以使程序在发生意外情况时更明显地失败。 例如&…...

R语言绘图-5-条形图(修改坐标轴以及图例等)
0. 说明: 1. 绘制条形图; 2. 添加文本并调整位置; 3. 调整x轴刻度的字体、角度及颜色; 4. 在导出pdf时,如果没有字体,该怎么解决问题; 1. 结果: 2. 代码: library(ggp…...

uniapp自定义权限菜单,动态tabbar
已封装为组件,亲测4个菜单项目可以切换, 以下为示例,根据Storage 中 userType 的 值,判断权限菜单 <template><view class"tab-bar pb10"><view class"tabli" v-for"(tab, index) in ta…...

ubuntu20.04配置解压版mysql5.7
目录 1.创建mysql 用户组和用户2.下载 MySQL 5.7 解压版3.解压 MySQL 文件4.将 MySQL 移动到适当的目录5.更改mysql目录所属的用户组和用户,以及权限6.进入mysql/bin/目录,安装初始化7.编辑/etc/mysql/my.cnf配置文件8.启动 MySQL 服务:9.建立…...

【js】vue获取document.getElementById(a)为null
需求 在菜单A页面点击某个元素携带id跳转到B详情页面,B页面获取该id元素的offsetTop, 并自动滚动到该元素处 问题 跳转到B详情页面, 在mounted获取到document.getElementById(a)为null, 因为整个详情页面是从后端获取来渲染的数据, 因此此时dom元素还未渲染出来,…...

系列六、Mybatis的一级缓存
一、概述 Mybatis一级缓存的作用域是同一个SqlSession,在同一个SqlSession中执行两次相同的查询,第一次执行完毕后,Mybatis会将查询到的数据缓存起来(缓存到内存中), 第二次执行相同的查询时,会…...

用中文编程工具给澳大利亚客户定制开发的英文版服装进销存软件应用实例
用中文编程工具给澳大利亚客户定制开发的英文版服装进销存软件应用实例 软件从2016年一直用到现在,而且开的分店也是安装的这个软件,上图是定制打印的格式。 该编程工具不但可以连接硬件,而且可以开发大型的软件。 编程系统化课程总目录及明…...

geoserver 的跨域问题怎么解决
文章目录 问题分析问题 geoserver 发生跨域问题报错 分析 要解决 GeoServer 的跨域问题,可以通过配置 GeoServer 的 web.xml 文件来启用跨域资源共享(CORS)。以下是一些简单的步骤来实现这一点: 找到 GeoServer 的安装目录下的 webapps/geoserver/WEB-INF 文件夹。在该文…...

SQL语法实践(一)
文章 原文链接 实践 CREATE TABLE friend(fid INT NOT NULL,NAME VARCHAR(10) NOT NULL,age INT NOT NULL,adress VARCHAR(10) )SHOW TABLES; SELECT * FROM friend; SELECT fid,NAME FROM friend;INSERT INTO friend VALUES(1,Jack,18,Tianjing); INSERT INTO friend VALUE…...

路由器如何设置IP地址
IP地址是计算机网络中的关键元素,用于标识和定位设备和主机。在家庭或办公室网络中,路由器起到了连接内部设备和外部互联网的关键作用。为了使网络正常运行,需要正确设置路由器的IP地址。本文将介绍如何设置路由器的IP地址,以确保…...

自动驾驶算法(一):Dijkstra算法讲解与代码实现
目录 0 本节关键词:栅格地图、算法、路径规划 1 Dijkstra算法详解 2 Dijkstra代码详解 0 本节关键词:栅格地图、算法、路径规划 1 Dijkstra算法详解 用于图中寻找最短路径。节点是地点,边是权重。 从起点开始逐步扩展,每一步为一…...

MS5910PA为行业内领先的可配置10bit到16bit分辨率的旋变数字转换器,可替代AD2S1210
MS5910PA 是一款可配置 10bit 到 16bit 分辨率的旋 变数字转换器。片上集成正弦波激励电路,正弦和余弦 允许输入峰峰值幅度为 2.3V 到 4.0V ,频率范围为 2kHz 至 20kHz 。 转换器可并行或串行输出角度和速度对应的 数字量。 MS5910PA 采…...

Random指定随机种子遇到的坑
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言指定随机种子出现的问题?总结 前言 业务中,之前有一个抽奖的需求,之初想让固定的奖品和玩家绑定一个固定的池子,…...

2023云栖大会:属于开发者的狂欢
就在10月31日这天,杭州云栖小镇热闹非凡,第八届云栖大会在杭州云栖小镇盛大举行。这次大会以“聚焦大模型与生成式AI”为主题,开发者们齐聚一堂,共同探讨前沿技术趋势,以及如何将这些技术应用到实际业务场景中。 当然…...

jsp 网上订餐Myeclipse开发mysql数据库web结构java编程计算机网页项目
选题目的 本设计课题为网上订餐系统设计与实现,提供无纸化点餐、支付,实现点餐快捷,方便管理。餐厅电子化是目前的潮流和趋势,大多数企业都将公司内部运营流程电子化。网上订餐管理系统应运而生,能够有效提高公司的管…...

优化大表分页查询性能:大表LIMIT 1000000, 10该怎么优化?
在处理大数据量的MySQL表时,我们经常会遇到一个问题:当我们尝试使用LIMIT语句进行分页查询时,性能会随着偏移量的增加而显著下降。例如,SELECT * FROM table LIMIT 1000000, 10 这样的查询可能会非常慢。那么,我们应该…...

ubuntu PX4 vscode stlink debug设置
硬件 stlink holybro debug板 pixhawk4 安装openocd 官方文档,但是第一步安装建议从源码安装,bug少很多 github链接 编译安装,参考 ./bootstrap (when building from the git repository)./configure [options]makesudo make install安装后…...

Flask的一种启动方式和三种托管方式
1. 原生启动 Flask 支持使用原生的 app.run() 方法来启动应用程序。这种方法是最简单、最基本的启动方式,适用于开发环境和小型应用程序。 from flask import Flaskapp Flask(__name__)app.route(/) def hello_world():return Hello, World!if __name__ __main__…...

cudnn too short
原因是libcudnn.so为软链接,相当于快捷键,但是没有映射到真正的libcudnn.so.8.9.5上 cd /usr/local/cuda-11.6/lib64 ln -s libcudnn.so.8.9.5 libcudnn.so.8...