简介

移动的开发中,大家可能最头疼的就是不同设备的规格了,现在设备这么多,如何才能在诸多的设备中找到合适的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的更多相关文章

  1. 【iOS开发系列】UIDevice设备信息

    [1] 推断是否是横向屏: BOOL b=UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation); 获取设备uniqu ...

  2. AmiGO2:在线浏览和查询GO信息的利器

    GO数据库的信息是非常庞大的,为了有效的检索和浏览GO数据库的信息,官方提供了AmiGO, 可以方便的浏览,查询和下载对应信息,官网如下 http://amigo.geneontology.org/a ...

  3. CUDA查询和选取设备信息

    CUDA查询设备信息 CUDA C中的cudaGetDeviceProperties函数可以很方便的获取到设备的信息,函数原型是: cudaError_t CUDARTAPI cudaGetDevic ...

  4. 【CUDA 基础】2.4 设备信息

    title: [CUDA 基础]2.4 设备信息 categories: CUDA Freshman tags: CUDA Device Information toc: true date: 201 ...

  5. C#:基于WMI查询USB设备信息 及 Android设备厂商VID列表

    /* ---------------------------------------------------------- 文件名称:WMIUsbQuery.cs 作者:秦建辉 MSN:splashc ...

  6. Windows下USB磁盘开发系列三:枚举系统中U盘、并获取其设备信息

    前面我们介绍了枚举系统中的U盘盘符(见<Windows下USB磁盘开发系列一:枚举系统中U盘的盘符>).以及获取USB设备的信息(见<Windows下USB磁盘开发系列二:枚举系统中 ...

  7. MDNS的漏洞报告——mdns的最大问题是允许广域网的mdns单播查询,这会暴露设备信息,或者被利用用于dns放大攻击

    Vulnerability Note VU#550620 Multicast DNS (mDNS) implementations may respond to unicast queries ori ...

  8. blkid---对系统块设备信息查询

    在Linux下可以使用blkid命令对查询设备上所采用文件系统类型进行查询.blkid主要用来对系统的块设备(包括交换分区)所使用的文件系统类型.LABEL.UUID等信息进行查询.要使用这个命令必须 ...

  9. C#使用Xamarin开发可移植移动应用终章(11.获取设备信息与常用组件,开源一个可开发模版.)

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 本系列,终 ...

随机推荐

  1. Note -「Dijkstra 求解 MCMF」

    食用前请先了解 SPFA + Dinic/EK 求解 MCMF. Sol. 总所周知,SPFA 牺牲了.于是我们寻求一些更稳定的算法求解 MCMF. 网络流算法的时间属于玄学,暂且判定为混乱中的稳定. ...

  2. Docker搭建STF私有移动测试云平台

    一. STF介绍 Smartphone Test Farm(简称STF)是一个web应用程序,主要用于从指定的浏览器中远程调试智能手机.智能手表等,可远程调试超过160多台设备.STF可以便捷的管理移 ...

  3. MES对接Simba实现展讯平台 IMEI 写号与耦合测试

    文章开始之前,必须对Simba工具点一个大大的赞,Simba为了适应市面上不同厂家开发的 MES 系统,特地开发了统一的接口,各个 MES 厂家只需要按照接口规范去做开发,然后将中间件加载到 Simb ...

  4. Min GW 安装教程(转载)

    下载方式一:1.百度搜索关键词"mingw",点击第一个:2.进入官网后,点击右上角的"Downloads":3.进入第三个页面后,点击"mingw- ...

  5. 【Meetup回顾】Apache DolphinScheduler在联通的实践和二次开发经验分享

    在由 openLooKeng 社区主办,Apahce DolphinScheduler社区.Apache Pulsar 社区.示说网协办的联合 Meetup 上,来自联通数字科技的王兴杰老师分享了Do ...

  6. Luogu3435 [POI2006]OKR-Periods of Words (KMP)

    \(next\)应用,将原串视作最长前缀复制后的子串 #include <iostream> #include <cstdio> #include <cstring> ...

  7. Luogu1064 金明的预算方案 (有依赖的背包)

    枚举多个状态 #include <iostream> #include <cstdio> #include <cstring> #include <algor ...

  8. BZOJ3572/Luogu3233 [Hnoi2014]世界树 (虚树) (Unfinished)

    我太弱了,这叼题先搁着把,来日方长,自有切时... ...或许吧 #include <iostream> #include <cstdio> #include <cstr ...

  9. bbs项目解读

    1.注册功能 具体的效果图如下: 注册功能涉及到的逻辑步骤: 1.搭建前端html页面 2.向后端提交用户输入数据 3.对用户输入的数据格式进行校验 4.页面输入数据格式错误,及时向用户进行提示/正确 ...

  10. IDEA:库源与类的字节码不匹配

    在我配置pom.xml文件后,进行代码编辑,发现引入的方法并不是想要的内容,然后我就进入下载源码后进入到源码中发现我想要的方法和导入的jar包内的源码方法并不相同 ,于是到jar的存放地址中将其他版本 ...