【Flutter 專題】94 初識 MediaQuery

      網友投稿 999 2025-03-31

      當我們同時為手機和平板適配編寫 app 針對不同屏幕尺寸進行 UI 布局或當用戶偏好設置較大字號或是想要最大限度等減少動畫等;此時就需要 MediaQuery 來幫我們獲取所用設備的信息以及用戶設置的偏好信息;


      MediaQuery

      MediaQuery 一直存在于 WidgetsApp 和 MaterialApp 中,MediaQuery 繼承自 InheritedWidget 是一個單獨的 Widget,但一般通過 MediaQuery.of(context) 來獲取相關信息;

      當相關信息發生變化,例如屏幕旋轉等時,屏幕中 Widget 會重新構建,以保持最新狀態;我們可以通過 MediaQuery 構造函數和提供的靜態方法手動設置對應的相關信息;

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

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

      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, });

      size 為媒介的尺寸大小,以邏輯像素為單位;

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

      devicePixelRatio 為像素密度;與設備物理像素有關,與橫豎屏等無關;

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

      orientation 為橫豎屏,Orientation.landscape 為橫屏,Orientation.portrait 為豎屏;

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

      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}');

      platformBrightness 為當前設備的亮度模式;注意調整屏幕亮度并不會改變該模式,與當前系統支持的黑暗模式和明亮模式相關;

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

      alwaysUse24HourFormat 為當前設備是否為 24 小時制;

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

      accessibleNavigation 為是否使用 TalkBack 或 VoiceOver 之類的輔助功能與應用程序進行交互,用以輔助視力障礙人群;

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

      invertColors 為是否使用顏色反轉,主要用于 iOS 設備;

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

      highContrast 為用戶是否要求前景與背景之間的對比度高,主要用于 iOS 設備;

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

      disableAnimations 為平臺是否要求禁用或減少動畫;

      print('是否減少動畫 -> ${MediaQuery.of(context).disableAnimations}');

      boldText 為平臺是否要求使用粗體;

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

      padding 為屏幕內邊距,一般是劉海兒屏或異形屏中被系統遮擋部分邊距;

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

      viewInsets 為鍵盤彈出時等遮擋屏幕邊距,其中 viewInsets.bottom 為鍵盤高度;

      print('鍵盤遮擋內邊距 -> ${MediaQuery.of(context).viewInsets}');

      systemGestureInsets 為手勢邊距,如 Android Q 之后添加的向左滑動關閉頁面等;

      print('系統手勢邊距 -> ${MediaQuery.of(context).systemGestureInsets}');

      viewPadding 小菜理解為視圖內邊距,為屏幕被劉海兒屏或異形屏中被系統遮擋部分,從 MediaQuery 邊界的邊緣計算;此值是保持不變;例如,屏幕底部的軟件鍵盤可能會覆蓋并占用需要底部填充的相同區域,因此不會影響此值;

      print('系統手勢邊距 -> ${MediaQuery.of(context).systemGestureInsets}');

      physicalDepth 為設備物理層級,小菜暫時還未想到對應的應用場景;

      print('設備物理層級 -> ${MediaQuery.of(context).physicalDepth}');

      Tips

      小菜在嘗試獲取其他子 Widget Size 時,有兩點需要注意,首先要設置一個全局的 GlobalKey 來獲取當前位置,key 需要為唯一的;第二通過 GlobalKey().currentContext 獲取 BuildContext 上下文環境,從而獲取對應尺寸;

      【Flutter 專題】94 初識 MediaQuery

      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 的應用和理解還不夠深入;如有錯誤請多多指導!

      來源: 阿策小和尚

      flutter

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:全自動甘特圖
      下一篇:100個最常問的JavaScript面試問答-第1部分
      相關文章
      久久久久亚洲精品美女| 国产成人精品亚洲精品| 亚洲色精品aⅴ一区区三区| yy6080亚洲一级理论| 亚洲精品天堂无码中文字幕| 亚洲一线产区二线产区区| 伊人久久五月丁香综合中文亚洲| 亚洲福利一区二区三区| 亚洲精品国产情侣av在线| 激情内射亚洲一区二区三区| 亚洲欧洲第一a在线观看| 亚洲色四在线视频观看| 亚洲今日精彩视频| 午夜影视日本亚洲欧洲精品一区| 亚洲乱色熟女一区二区三区丝袜| 亚洲尤码不卡AV麻豆| 亚洲中文字幕无码一久久区| 亚洲日本va在线视频观看| 国产亚洲3p无码一区二区| 亚洲国产精品福利片在线观看| 亚洲成av人片天堂网| 亚洲AV人无码激艳猛片| 久久亚洲精品成人av无码网站| 老司机亚洲精品影院无码| 亚洲精品人成电影网| 亚洲一区在线视频| 亚洲熟女综合色一区二区三区| 亚洲人成网站在线在线观看| 亚洲欧美熟妇综合久久久久| 亚洲av成人中文无码专区| 亚洲av午夜成人片精品电影| 亚洲综合区小说区激情区| 亚洲精品无码不卡在线播放HE| 亚洲产国偷V产偷V自拍色戒 | 亚洲欧美国产日韩av野草社区| 亚洲Av永久无码精品黑人| 亚洲AV成人潮喷综合网| 伊人婷婷综合缴情亚洲五月| 亚洲区小说区图片区QVOD| 亚洲人成网址在线观看| 亚洲人配人种jizz|