MediaQuery——flutter移动开发中查询设备信息的利器
在移动开发中,不同设备的规格可能是大家最大的问题。现在设备这么多,我们如何在众多设备中找到合适的widget位置呢?画画呢?
别担心,Flutter为我们提供了一个利器,叫MediaQuery,我们来看看吧。
MediaQuery详解
MediaQuery 从名字上看,就是媒体询问的意思。它可以查询很多东西,它可以查询你的应用程序当前窗口的信息,它可以查询你指定的一个小部件的信息等等。它非常强大。
首先我们来看看MediaQuery是什么。具体来说,MediaQuery继承了InheritedWidget:
class MediaQuery extends InheritedWidget
那么InheritedWidget是什么?为什么MediaQuery需要InheritedWidget的继任者?
很多时候我们需要从widget的子widget中获取父widget对象。 InheritedWidget是一个可以提供简单获取方法的对象。
在InheritedWidget中可以实现of方法,通过调用BuildContext.dependOnInheritedWidgetOfExactType可以从上下文中获取最近的InheritedWidget对象。
这里,由于MediaQuery是一个媒体查询工具,我们可能需要在任何时间、很多地方获取对象,所以这里最好使用InheritedWidget。
MediaQuery 属性
MediaQuery 只有两个属性,分别是 MediaQuery 数据类型的数据和 Widget 类型的后代。
MediaQuery数据是一种类似类的结构,用于存储有关各种媒体状态的信息。
首先,让我们看一下MediaQuery数据构造器:
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, })
正如你所看到的,MediaQuery数据包含许多有用的属性。下面我们来详细了解一下具体内容。
第一个是尺寸,表示媒体逻辑像素的尺寸。大家要注意,这里的尺寸代表的是逻辑像素尺寸。
有逻辑像素和物理像素。前者表示在任何设备上都相同的逻辑大小,而后者表示实际物理设备支持的像素大小。两者可以不同。一个物理像素可以代表多个逻辑像素,这种匹配由 devicePixelRatio 属性确定。
devicePixelRatio 表示有多少个逻辑像素代表一个物理像素。 devicePixelRatio 不需要是整数。例如,在 Nexus 6 设备上,此 devicePixelRatio=3.5。
接下来是textScaleFactor,它表示一个逻辑像素可以表示多少个字体像素。或者您可以将其视为字体大小。
例如textScaleFactor=1.5,那么就表示渲染的字体比给定的字体大50%。
然后是平台亮度,代表设备亮度。最常见的是明亮模式或黑暗模式。
viewInsets 表示被系统用户界面完全覆盖的部分。例如,当我们进行键盘输入时,就会弹出键盘界面。
填充表示被系统用户界面部分覆盖且不完全可见的部分。通常是系统状态栏,就像iPhone上的伤口一样。
viewPadding 表示被系统用户界面部分覆盖、无法完全看到的部分。通常是系统状态栏,就像iPhone上的伤口一样。
哇,看起来padding和viewPadding是一样的,但这是真的吗?
两者通常是相同的,只有在出现键盘输入界面时才会有所不同。
简单来说,viewPadding 是固定的,其大小不随键盘视图的变化而改变。衬垫是可更换的。当键盘展开且系统状态栏隐藏时,其底部值为0。
systemGestureInsets 是一个特殊的手势区域。该区域只能识别部分手势指令,而不是所有手势指令,所以需要这样的属性。
alwaysUse24HourFormat表示是否使用24小时时间格式。
accessibleNavigation 指示用户是否使用任何辅助服务与应用程序交互。
还有其他可以使用的基本功能,例如高对比度、禁用动画、粗体文本、导航模式和方向。
MediaQuery的另一个属性是孩子。
MediaQuery构造函数
除了最常见的构造函数之外,MediaQuery还有三个构造函数,分别是Future.removePadding、Future.removeViewInsets、Future.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。 。
我们看到返回了一个新的MediaQuery,其中data部分使用MediaQuery.of(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当然也可以用在其他需要确定媒体属性的地方。大家可以仔细体验一下。
总结
MediaQuery是flutter中一个非常方便的工具,用于检测媒体属性。按照MediaQuery的说法,我们可以创建一个更具互动性的APP。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。