flutter系列之:查询设备信息的利器:MediaQuery
简介
移动的开发中,大家可能最头疼的就是不同设备的规格了,现在设备这么多,如何才能在诸多的设备中找到合适的widget的位置来进行绘制呢?
不用怕,在flutter中为我们提供了一个叫做MediaQuery的利器,大家一起来看看吧。
MediaQuery详解
MediaQuery从名字上来看,它的意思是媒体查询。它可以查询的东西就多了,可以查询当前你app的窗口信息,查询你指定的某个widget的信息等等,非常的强大。
我们先来看下MediaQuery到底是什么。 具体来说MediaQuery继承自InheritedWidget:
class MediaQuery extends InheritedWidget
那么什么是InheritedWidget呢?为什么MediaQuery需要继承InheritedWidget呢?
很多时候,我们需要从widget的子widget中获取到父widget对象,InheritedWidget就是一个可以提供简单获取方法的对象。
在InheritedWidget中可以实现of方法,通过调用BuildContext.dependOnInheritedWidgetOfExactType来从context中获取最临近的InheritedWidget对象。
这里,因为MediaQuery是一个媒体查询工具,所以我们可能需要在很多地方随时随地的进行对象的获取,那么这里使用InheritedWidget就是再好不过了。
MediaQuery的属性
MediaQuery的自有属性只有两个,分别是MediaQueryData类型的data和Widget类型的child。
MediaQueryData是一个类似于结构体的类,用来存储各种Media的状态信息。
我们先来看下MediaQueryData的构造函数:
const MediaQueryData({
this.size = Size.zero,
this.devicePixelRatio = 1.0,
this.textScaleFactor = 1.0,
this.platformBrightness = Brightness.light,
this.padding = EdgeInsets.zero,
this.viewInsets = EdgeInsets.zero,
this.systemGestureInsets = EdgeInsets.zero,
this.viewPadding = EdgeInsets.zero,
this.alwaysUse24HourFormat = false,
this.accessibleNavigation = false,
this.invertColors = false,
this.highContrast = false,
this.disableAnimations = false,
this.boldText = false,
this.navigationMode = NavigationMode.traditional,
})
可以看到,MediaQueryData中包含了很多有用的属性,我们来详细看一下具体的内容。
首先是表示media logical pixels大小的size。大家要注意的是,这里的size表示的是逻辑pixels的大小。
有logical pixels,就有Physical pixels,前者表示的逻辑大小,在任何设备上都是一样的,而后者表示的是真实的物理设备所支持的像素大小。这两种是可以不同的。一个物理像素可能代表多个逻辑像素,这个对应关系就是由devicePixelRatio这个属性来决定的。
devicePixelRatio表示的是一个物理像素代表多少个逻辑像素。devicePixelRatio并不要求是整数,比如在Nexus 6中,这个devicePixelRatio=3.5。
接下来是textScaleFactor,表示一个逻辑像素能够表示多少个字体像素。或者你可以将其理解为字体的放大程度。
比如textScaleFactor=1.5,那么它的意思是呈现出来的字体要比给定的字体大50%。
然后是platformBrightness,表示的是设备的明亮程度。最常见的比如说明亮模式或者黑暗模式等。
viewInsets指的是被系统UI所完全遮罩的部分,比如说我们在进行键盘输入的时候,会弹起键盘界面。
padding表示的是被系统UI所部分遮罩,并不能完全看见的部分,通常是系统状态栏,比如iphone中的刘海等。
viewPadding表示的是被系统UI所部分遮罩,并不能完全看见的部分,通常是系统状态栏,比如iphone中的刘海等。
哇喔,看起来padding和viewPadding是一样的,那么事实是否如此呢?
这两者通常情况下是一样的,只有在出现键盘输入界面的时候两者就会发生不同。
简单来说,viewPadding是固定的,它的大小不会随键盘的显示而发生变化,Padding是可变化的,当键盘弹起,系统状态栏被遮罩的时候,它的bottom值就是0。
systemGestureInsets是一个特殊的手势区域,在这个区域里面只能识别部分的手势指令,而不能识别所有的手势指令,所以需要这样的一个属性。
alwaysUse24HourFormat表示是否使用24小时的时间格式。
accessibleNavigation表示用户是否使用了一些accessibility服务来和应用进行交互。
还有其他的一些属性比如highContrast,disableAnimations,boldText,navigationMode和orientation等基础的属性可以使用。
MediaQuery的另外一个属性就是child了。
MediaQuery的构造函数
MediaQuery除了最常规的构造函数之外,还有三个构造函数,分别是MediaQuery.removePadding,MediaQuery.removeViewInsets和MediaQuery.removeViewPadding。
这三个构造函数都是通过传入一个指定的context和child来构造MediaQuery,但是他们都相应的移出了一些属性。根据名字就可以看出来,这三个分别移出的是padding,viewInsets和viewPadding。
我们以removePadding为例,看一下具体的实现流程:
factory MediaQuery.removePadding({
Key? key,
required BuildContext context,
bool removeLeft = false,
bool removeTop = false,
bool removeRight = false,
bool removeBottom = false,
required Widget child,
}) {
return MediaQuery(
key: key,
data: MediaQuery.of(context).removePadding(
removeLeft: removeLeft,
removeTop: removeTop,
removeRight: removeRight,
removeBottom: removeBottom,
),
child: child,
);
}
removePadding方法需要传入四个额外的参数来表示是否需要移出padding的left,top,right或者bottom。
我们可以看到返回了一个新的MediaQuery,其中data部分使用了MediaQuery.of(context)来获取context最近的MediaQuery,然后调用它的removePadding方法将对应的padding属性删除。
MediaQuery的使用
讲完MediaQuery的构造函数,接下来我们看一下MediaQuery常用的使用场景。
其实MediaQuery最常见的用处就是来判断设备的大小,从而根据不同设备的大小来进行页面的调整。
比如下面的getSize方法:
enum ScreenSize { Small, Normal, Large, ExtraLarge }
ScreenSize getSize(BuildContext context) {
double deviceWidth = MediaQuery.of(context).size.shortestSide;
if (deviceWidth > 900) return ScreenSize.ExtraLarge;
if (deviceWidth > 600) return ScreenSize.Large;
if (deviceWidth > 300) return ScreenSize.Normal;
return ScreenSize.Small;
}
我们通过MediaQuery.of(context)拿到MediaQuery,然后通过size的shortestSide属性获得设备的宽度,然后根据设备的宽度跟特定的宽度进行对比,从而判断设备屏幕的大小。
当然,MediaQuery还可以用在其他需要检测Media属性的地方,大家可以仔细体会。
总结
MediaQuery是flutter中一个非常方便的工具,用来检测media的属性情况,根据MediaQuery,我们可以做出更加富有交互性的APP。
更多内容请参考 http://www.flydean.com/50-flutter-mediaquery/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
flutter系列之:查询设备信息的利器:MediaQuery的更多相关文章
- 【iOS开发系列】UIDevice设备信息
[1] 推断是否是横向屏: BOOL b=UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation); 获取设备uniqu ...
- AmiGO2:在线浏览和查询GO信息的利器
GO数据库的信息是非常庞大的,为了有效的检索和浏览GO数据库的信息,官方提供了AmiGO, 可以方便的浏览,查询和下载对应信息,官网如下 http://amigo.geneontology.org/a ...
- CUDA查询和选取设备信息
CUDA查询设备信息 CUDA C中的cudaGetDeviceProperties函数可以很方便的获取到设备的信息,函数原型是: cudaError_t CUDARTAPI cudaGetDevic ...
- 【CUDA 基础】2.4 设备信息
title: [CUDA 基础]2.4 设备信息 categories: CUDA Freshman tags: CUDA Device Information toc: true date: 201 ...
- C#:基于WMI查询USB设备信息 及 Android设备厂商VID列表
/* ---------------------------------------------------------- 文件名称:WMIUsbQuery.cs 作者:秦建辉 MSN:splashc ...
- Windows下USB磁盘开发系列三:枚举系统中U盘、并获取其设备信息
前面我们介绍了枚举系统中的U盘盘符(见<Windows下USB磁盘开发系列一:枚举系统中U盘的盘符>).以及获取USB设备的信息(见<Windows下USB磁盘开发系列二:枚举系统中 ...
- MDNS的漏洞报告——mdns的最大问题是允许广域网的mdns单播查询,这会暴露设备信息,或者被利用用于dns放大攻击
Vulnerability Note VU#550620 Multicast DNS (mDNS) implementations may respond to unicast queries ori ...
- blkid---对系统块设备信息查询
在Linux下可以使用blkid命令对查询设备上所采用文件系统类型进行查询.blkid主要用来对系统的块设备(包括交换分区)所使用的文件系统类型.LABEL.UUID等信息进行查询.要使用这个命令必须 ...
- C#使用Xamarin开发可移植移动应用终章(11.获取设备信息与常用组件,开源一个可开发模版.)
前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 本系列,终 ...
随机推荐
- surging作者出具压测结果
前言 首先回应下@wen-wen 所贴的压测报告,我也把我和客户压测碰到的问题,和压测结果贴出来,这个结果是由客户提供的.不会有任何的舞弊手脚问题 问题一:Task.Run慎用 首先在最新的社区版本已 ...
- Note -「Dsu On Tree」学习笔记
前置芝士 树连剖分及其思想,以及优化时间复杂度的原理. 讲个笑话这个东西其实和 Dsu(并查集)没什么关系. 算法本身 Dsu On Tree,一下简称 DOT,常用于解决子树间的信息合并问题. 其实 ...
- Apache Hudi数据跳过技术加速查询高达50倍
介绍 在 Hudi 0.10 中,我们引入了对高级数据布局优化技术的支持,例如 Z-order和希尔伯特空间填充曲线(作为新的聚类算法),即使在经常使用过滤器查询大表的复杂场景中,也可以在多个列而非单 ...
- linux学习随笔2之防火墙
centos7默认使用的防火墙是firewalld 查看所有打开的端口: firewall-cmd --zone=public --list-ports 更新防火墙规则: firewall-cmd - ...
- Vue 状态管理之vuex && {mapState,mapGetters}
1 # 一.理解vuex 2 1.概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读写),也是一种组件间通信的方式,且适用于任意组件间 ...
- Spring 请求方法的调用原理(Controller)和请求参数的获取的原理
1.请求映射原理 所有的请求都会经过DispatcherServlet这个类,先了解它的继承树 本质还是httpServlet 原理图 测试 request请求携带的参数 从requestMapp ...
- MySQL为什么"错误"选择代价更大的索引
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 MySQL优化器索引选择迷思. 高鹏(八怪)对本文亦有贡献. 1. 问题描述 群 ...
- 4 亿用户,7W+ 作业调度难题,Bigo 基于 Apache DolphinScheduler 巧化解
点击上方 蓝字关注我们 ✎ 编 者 按 成立于 2014 年的 Bigo,成立以来就聚焦于在全球范围内提供音视频服务.面对 4 亿多用户,Bigo 大数据团队打造的计算平台基于 Apache Dolp ...
- navicat创建连接 2002-can‘t connect to server on ....
环境: 系统:centos7 生产环境:docker 中部署MySQL 报错提示符:"2002-Can't connect to server on '192.168.200.22'(100 ...
- 10种有用的Linux Bash_Completion 命令示例
摘要:我们可以对这个 bash 补全进行加速,并使用 complete 命令将其提升到一个新的水平. 本文分享自华为云社区<有用的 Linux Bash_Completion 命令示例(Ster ...