关于flutter:flutter系列之查询设备信息的利器MediaQuery

45次阅读

共计 3912 个字符,预计需要花费 10 分钟才能阅读完成。

简介

挪动的开发中,大家可能最头疼的就是不同设施的规格了,当初设施这么多,如何能力在诸多的设施中找到适合的 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/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!

正文完
 0