Flutter 94: 初识 MediaQuery

      当我们同时为手机和平板适配编写 app 针对不同屏幕尺寸进行 UI 布局或当用户偏好设置较大字号或是想要最大限度等减少动画等;此时就需要 MediaQuery 来帮我们获取所用设备的信息以及用户设置的偏好信息;

MediaQuery

      MediaQuery 一直存在于 WidgetsAppMaterialApp 中,MediaQuery 继承自 InheritedWidget 是一个单独的 Widget,但一般通过 MediaQuery.of(context) 来获取相关信息;

      当相关信息发生变化,例如屏幕旋转等时,屏幕中 Widget 会重新构建,以保持最新状态;我们可以通过 MediaQuery 构造函数和提供的静态方法手动设置对应的相关信息;

1. MediaQuery()

const MediaQuery({
    Key key,
    @required this.data,
    @required Widget child,
})

2. MediaQuery.removePadding() 删除内边距

factory MediaQuery.removePadding({
    Key key,
    @required BuildContext context,
    bool removeLeft = false,
    bool removeTop = false,
    bool removeRight = false,
    bool removeBottom = false,
    @required Widget child,
})

3. MediaQuery.removeViewInsets() 删除视图内边距

factory MediaQuery.removeViewInsets({
    Key key,
    @required BuildContext context,
    bool removeLeft = false,
    bool removeTop = false,
    bool removeRight = false,
    bool removeBottom = false,
    @required Widget child,
})

MediaQueryData

      MediaQueryData 包含关于媒介的相关信息;一般通过 MediaQuery.of(context) 获取;

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.physicalDepth = double.maxFinite,
    this.alwaysUse24HourFormat = false,
    this.accessibleNavigation = false,
    this.invertColors = false,
    this.highContrast = false,
    this.disableAnimations = false,
    this.boldText = false,
});

1. size

      size 为媒介的尺寸大小,以逻辑像素为单位;

print('屏幕 Size -> ${MediaQuery.of(context).size}');

print('按钮 Size -> ${_itemExpandedKey.currentContext.size}');
print('文字 Size -> ${_itemTextKey.currentContext.size}');
print('文字 Size -> ${MediaQuery.of(_itemTextKey.currentContext).size}');

2. devicePixelRatio

      devicePixelRatio 为像素密度;与设备物理像素有关,与横竖屏等无关;

print('屏幕像素比 -> ${MediaQuery.of(context).devicePixelRatio}');

3. orientation

      orientation 为横竖屏,Orientation.landscape 为横屏,Orientation.portrait 为竖屏;

print('横竖屏 -> ${MediaQuery.of(context).orientation}');

4. textScaleFactor

      textScaleFactor
每个逻辑像素的字体像素数,小菜理解为字体的像素比;注意,小菜设置了默认字体像素密度为标准的 1.2 倍之后调整设备系统字号,其 1.2 倍依旧是以标准字号为基础扩大 1.2 倍;

print('字体像素比 -> ${MediaQuery.of(context).textScaleFactor}');

MediaQuery(data: MediaQuery.of(context).copyWith(textScaleFactor: 1.2),
    child: Text('字体像素比 * 1.2', style: TextStyle(color: Colors.white, fontSize: 16.0));
print('字体像素比 * 1.2 -> ${MediaQuery.of(context).copyWith(textScaleFactor: 1.2).textScaleFactor}');

5. platformBrightness

      platformBrightness 为当前设备的亮度模式;注意调整屏幕亮度并不会改变该模式,与当前系统支持的黑暗模式和明亮模式相关;

print('亮度模式 -> ${MediaQuery.of(context).platformBrightness}');

6. alwaysUse24HourFormat

      alwaysUse24HourFormat 为当前设备是否为 24 小时制;

print('24 小时制 -> ${MediaQuery.of(context).alwaysUse24HourFormat}');

7. accessibleNavigation

      accessibleNavigation 为是否使用 TalkBackVoiceOver 之类的辅助功能与应用程序进行交互,用以辅助视力障碍人群;

print('亮度模式 -> ${MediaQuery.of(context).accessibleNavigation}');

8. invertColors

      invertColors 为是否使用颜色反转,主要用于 iOS 设备;

print('颜色反转 -> ${MediaQuery.of(context).invertColors}');

9. highContrast

      highContrast 为用户是否要求前景与背景之间的对比度高,主要用于 iOS 设备;

print('前后背景高对比度 -> ${MediaQuery.of(context).highContrast}');

10. disableAnimations

      disableAnimations 为平台是否要求禁用或减少动画;

print('是否减少动画 -> ${MediaQuery.of(context).disableAnimations}');

11. boldText

      boldText 为平台是否要求使用粗体;

print('是否使用粗体 -> ${MediaQuery.of(context).boldText}');

12. padding

      padding 为屏幕内边距,一般是刘海儿屏或异形屏中被系统遮挡部分边距;

print('内边距 -> ${MediaQuery.of(context).padding}');

13. viewInsets

      viewInsets 为键盘弹出时等遮挡屏幕边距,其中 viewInsets.bottom 为键盘高度;

print('键盘遮挡内边距 -> ${MediaQuery.of(context).viewInsets}');

14. systemGestureInsets

      systemGestureInsets 为手势边距,如 Android Q 之后添加的向左滑动关闭页面等;

print('系统手势边距 -> ${MediaQuery.of(context).systemGestureInsets}');

15. viewPadding

      viewPadding 小菜理解为视图内边距,为屏幕被刘海儿屏或异形屏中被系统遮挡部分,从 MediaQuery 边界的边缘计算;此值是保持不变;例如,屏幕底部的软件键盘可能会覆盖并占用需要底部填充的相同区域,因此不会影响此值;

print('系统手势边距 -> ${MediaQuery.of(context).systemGestureInsets}');

16. physicalDepth

      physicalDepth 为设备物理层级,小菜暂时还未想到对应的应用场景;

print('设备物理层级 -> ${MediaQuery.of(context).physicalDepth}');

Tips

      小菜在尝试获取其他子 Widget Size 时,有两点需要注意,首先要设置一个全局的 GlobalKey 来获取当前位置,key 需要为唯一的;第二通过 GlobalKey().currentContext 获取 BuildContext 上下文环境,从而获取对应尺寸;

var _itemExpandedKey = GlobalKey();
var _itemTextKey = GlobalKey();

Expanded(
    key: _itemExpandedKey,
    child: FlatButton(
        onPressed: () => _itemClick(2),
        child: Center(child: Text('按钮 Size', key: _itemTextKey, style: TextStyle(color: Colors.white, fontSize: 16.0))),
        color: Colors.purpleAccent.withOpacity(0.4)))

      MediaQuery 案例尝试


      小菜对于部分 MediaQueryData 的应用和理解还不够深入;如有错误请多多指导!

来源: 阿策小和尚

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容