在移动开发中,最让大家头疼的可能就是不同设备的规格问题。现在有这么多的设备,我们如何才能在众多的设备中找到合适的widget位置呢?画它?别怕,flutter里给我们提供了一个叫MediaQuery的利器,一起来看看吧。MediaQuery详解MediaQuery从名字上看,就是媒体查询的意思。它可以查询很多东西,你可以查询你app当前的窗口信息,查询你指定的某个widget的信息等等,非常强大。我们先看看什么是MediaQuery。具体来说,MediaQuery继承自InheritedWidget:classMediaQueryextendsInheritedWidget那么什么是InheritedWidget呢?为什么MediaQuery需要继承InheritedWidget?很多时候,我们需要从widget的子widget中获取父widget对象,而InheritedWidget就是一个可以提供简单获取方法的对象。of方法可以在InheritedWidget中实现,通过调用BuildContext.dependOnInheritedWidgetOfExactType从上下文中获取最近的InheritedWidget对象。这里因为MediaQuery是一个媒体查询工具,我们可能需要在很多地方随时随地获取对象,所以这里使用InheritedWidget比较好。MediaQuery的属性MediaQuery自身的属性只有两个,分别是MediaQueryData类型的data和Widget类型的child。MediaQueryData是一个类结构类,用于存储各种媒体状态信息。先看MediaQueryData的构造函数:constMediaQueryData({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包含许多有用的属性。下面我们就来详细了解一下具体内容。第一个是表示媒体逻辑像素大小的大小。大家要注意,这里的大小代表的是逻辑像素的大小。有逻辑像素,也有物理像素。前者代表的逻辑大小在任何设备上都是一样的,而后者代表的是真实物理设备支持的像素大小。这两个可以不同。一个物理像素可能代表多个逻辑像素,这种对应关系由属性devicePixelRatio决定。devicePixelRatio表示一个物理像素代表多少个逻辑像素。devicePixelRatio不需要是整数,比如在Nexus6中,这个devicePixelRatio=3.5。接下来是textScaleFactor,表示一个逻辑像素可以表示多少个字体像素。或者你可以理解为字体的放大。例如textScaleFactor=1.5,那么表示渲染的字体比给定的字体大50%。然后是platformBrightness,表示设备的亮度。最常见的是亮模式或暗模式。viewInsets指的是完全被系统UI覆盖的部分。比如我们输入键盘,就会弹出键盘界面。padding表示被系统UI部分覆盖,不能完全看到的部分,通常是系统状态栏,比如iPhone中的刘海。viewPadding代表被系统UI部分覆盖,不能完全看到的部分,通常是系统状态栏,比如iphone中的刘海。哇,看起来padding和viewPadding是一样的,这是真的吗?这两个通常是一样的,只有出现键盘输入界面时,两者才会不同。简单的说,viewPadding是固定的,它的大小不会随着键盘的显示而变化。填充是可变的。当键盘弹出,系统状态栏被遮挡时,其底部值为0。systemGestureInsets是一个特殊的手势区域。该区域只能识别部分手势命令,不能识别所有手势命令,所以需要这样的属性。alwaysUse24HourFormat表示是否使用24小时制时间格式。accessibleNavigation指示用户是否使用某些辅助功能服务与应用程序进行交互。还可以使用其他基本属性,例如highContrast、disableAnimations、boldText、navigationMode和orientation。MediaQuery的另一个属性是child。MediaQuery的构造函数除了最常规的构造函数外,MediaQuery还有三个构造函数,分别是MediaQuery.removePadding、MediaQuery.removeViewInsets和MediaQuery.removeViewPadding。这三个构造函数通过传入指定的context和child来构造MediaQuery,但是它们都相应地移除了一些属性。根据名字可以看出去掉的三个是padding、viewInsets和viewPadding。下面以removePadding为例,看看具体的实现过程:,}){returnMediaQuery(key:key,data:MediaQuery.of(context).removePadding(removeLeft:removeLeft,removeTop:removeTop,removeRight:removeRight,removeBottom:removeBottom,),child:child,);}removePadding方法需要额外传入四个参数来表示是否需要移除左侧、顶部、右侧或底部的padding。我们可以看到返回了一个新的MediaQuery,其中data部分使用MediaQuery.of(context)获取了context最近的MediaQuery,然后调用其removePadding方法删除对应的padding属性。MediaQuery的使用说完了MediaQuery的构造函数,我们来看看MediaQuery的常用使用场景。其实MediaQuery最常见的用途就是判断设备的大小,从而根据不同设备的大小来调整页面。例如,下面的getSize方法:enumScreenSize{Small,Normal,Large,ExtraLarge}ScreenSizegetSize(BuildContextcontext){doubledeviceWidth=MediaQuery.of(context).size.shortestSide;如果(设备宽度>900)返回ScreenSize.ExtraLarge;如果(设备宽度>600)返回ScreenSize.Large;如果(设备宽度>300)返回ScreenSize.Normal;returnScreenSize.Small;}我们通过MediaQuery.of(context)获取到MediaQuery,然后通过size的shortestSide属性获取到设备的宽度,然后将设备的宽度与具体的宽度进行比较,从而确定设备的尺寸屏幕。当然MediaQuery也可以用在其他需要检测Media属性的地方,大家可以细细体会。总结MediaQuery是flutter中一个非常方便的工具,用来检测媒体属性,根据MediaQuery,我们可以制作出更具交互性的APP。更多内容请参考http://www.flydean.com/50-flutter-mediaquery/最流行的解读,最深刻的干货,最简洁的教程,很多你不知道的小技巧等着你你来发现!欢迎关注我的公众号:《程序那些事儿》,懂技术,更懂你!
