網站首頁 編程語言 正文
MediaQuery
通常情況下,不會直接將MediaQuery當作一個控件,而是使用MediaQuery.of
獲取當前設備的信息,用法如下:
var data = MediaQuery.of(context);
此方式必須放在MediaQuery作用域內,否則會拋出異常,MaterialApp和WidgetsApp都引入了MediaQuery,并且隨著屏幕的變化而導致重建,比如旋轉屏幕、彈出輸入框等。
MediaQueryData
MediaQueryData是MediaQuery.of
獲取數據的類型。說明如下:
屬性 | 說明 |
---|---|
size | 邏輯像素,并不是物理像素,類似于Android中的dp,邏輯像素會在不同大小的手機上顯示的大小基本一樣,物理像素 = size*devicePixelRatio。 |
devicePixelRatio | 單位邏輯像素的物理像素數量,即設備像素比。 |
textScaleFactor | 單位邏輯像素字體像素數,如果設置為1.5則比指定的字體大50%。 |
platformBrightness | 當前設備的亮度模式,比如在Android Pie手機上進入省電模式,所有的App將會使用深色(dark)模式繪制。 |
viewInsets | 被系統遮擋的部分,通常指鍵盤,彈出鍵盤,viewInsets.bottom表示鍵盤的高度。 |
padding | 被系統遮擋的部分,通常指“劉海屏”或者系統狀態欄。 |
viewPadding | 被系統遮擋的部分,通常指“劉海屏”或者系統狀態欄,此值獨立于padding和viewInsets,它們的值從MediaQuery控件邊界的邊緣開始測量。在移動設備上,通常是全屏。 |
systemGestureInsets | 顯示屏邊緣上系統“消耗”的區域輸入事件,并阻止將這些事件傳遞給應用。比如在Android Q手勢滑動用于頁面導航(ios也一樣),比如左滑退出當前頁面。 |
physicalDepth | 設備的最大深度,類似于三維空間的Z軸。 |
alwaysUse24HourFormat | 是否是24小時制。 |
accessibleNavigation | 用戶是否使用諸如TalkBack或VoiceOver之類的輔助功能與應用程序進行交互,用于幫助視力有障礙的人進行使用。 |
invertColors | 是否支持顏色反轉。 |
highContrast | 用戶是否要求前景與背景之間的對比度高, iOS上,方法是通過“設置”->“輔助功能”->“增加對比度”。此標志僅在運行iOS 13的iOS設備上更新或以上。 |
disableAnimations | 平臺是否要求盡可能禁用或減少動畫。 |
boldText | 平臺是否要求使用粗體。 |
orientation | 是橫屏還是豎屏。 |
獲取設備相關信息:
import 'package:demo202112/utils/common_appbar.dart'; import 'package:flutter/cupertino.dart'; import "package:flutter/material.dart"; class WyMediaQuery extends StatefulWidget { const WyMediaQuery({Key? key}) : super(key: key); @override _WyMediaQueryState createState() => _WyMediaQueryState(); } class _WyMediaQueryState extends State<WyMediaQuery> { @override Widget build(BuildContext context) { return Scaffold( appBar: getAppBar('MediaQuery'), body: MediaQuery(data: const MediaQueryData(), child: _getDeviceMediaInfo(),), ); } _getDeviceMediaInfo(){ //屏幕大小 Size mSize = MediaQuery.of(context).size; //密度 double mRatio = MediaQuery.of(context).devicePixelRatio; //設備像素 double width = mSize.width * mRatio; double height = mSize.height * mRatio; // 上下邊距 (主要用于 劉海 和 內置導航鍵) double topPadding = MediaQuery.of(context).padding.top; double bottomPadding = MediaQuery.of(context).padding.bottom; double textScaleFactor = MediaQuery.of(context).textScaleFactor; Brightness platformBrightness = MediaQuery.of(context).platformBrightness; EdgeInsets viewInsets = MediaQuery.of(context).viewInsets; EdgeInsets padding = MediaQuery.of(context).padding; bool alwaysUse24HourFormat = MediaQuery.of(context).alwaysUse24HourFormat; bool accessibleNavigation = MediaQuery.of(context).accessibleNavigation; bool invertColors = MediaQuery.of(context).invertColors; bool disableAnimations = MediaQuery.of(context).disableAnimations; bool boldText = MediaQuery.of(context).boldText; Orientation orientation= MediaQuery.of(context).orientation; // bool alwaysUse24HourFormat = MediaQuery.of(context).alwaysUse24HourFormat; return Container( padding: EdgeInsets.all(30), child: Column( children: [ Text('屏幕大小:${mSize.width} x ${mSize.height}'), Text('密度:${mRatio}'), Text('設備像素大小:${width} x ${height}'), Text('上邊劉海:${topPadding}'), Text('下邊導航:${bottomPadding}'), Text('textScaleFactor: ${textScaleFactor}'), Text('platformBrightness: ${platformBrightness}'), Text('viewInsets: ${viewInsets}'), Text('padding: ${padding}'), Text('alwaysUse24HourFormat: ${alwaysUse24HourFormat}'), Text('accessibleNavigation: ${accessibleNavigation}'), Text('invertColors: ${invertColors}'), Text('disableAnimations: ${disableAnimations}'), Text('boldText: ${boldText}'), Text('orientation: ${orientation}'), Text('orientation: ${orientation}'), ], ),); } }
運行效果:
隨著屏幕旋轉,設備信息跟著屏幕方向在變動。
使用場景
根據尺寸構建不同的布局
SafeArea控件就是通過MediaQuery.of
來實現的,平板和手機的(或者橫屏和豎屏)布局可能是不一樣的,布局判斷:
var screenSize = MediaQuery.of(context).size; if(screenSize.width>oneColumnLayout){ //平板布局 }else{ //手機布局 }
oneColumnLayout
表示一列布局的寬度。
系統字體變化
很多App都有一個功能就是調節字體大小,通過MediaQuery來實現,實現如下:
//textScaleFactor 從1變到1.5,字體會全部增大 var _data = MediaQuery.of(context).copyWith(textScaleFactor: 1.0); return Scaffold( appBar: getAppBar('MediaQuery'), body: MediaQuery(data: _data, child: _getDeviceMediaInfo(),), );
運行效果:
第三方屏幕的適配框架:
flutter_screenutil:用于調整屏幕和字體大小的顫振插件。讓你的UI在不同的屏幕尺寸上顯示合理的布局!
api適配:
ScreenUtil().setWidth(540) (dart sdk>=2.6 : 540.w) //根據屏幕寬度適配尺寸 ScreenUtil().setHeight(200) (dart sdk>=2.6 : 200.h) //根據屏幕高度適配尺寸(一般根據寬度適配即可) ScreenUtil().radius(200) (dart sdk>=2.6 : 200.r) //根據寬度或高度中的較小者進行調整 ScreenUtil().setSp(24) (dart sdk>=2.6 : 24.sp) //適配字體 12.sm // 取12和12.sp中的最小值 ScreenUtil.pixelRatio //設備的像素密度 ScreenUtil.screenWidth (dart sdk>=2.6 : 1.sw) //設備寬度 ScreenUtil.screenHeight (dart sdk>=2.6 : 1.sh) //設備高度 ScreenUtil.bottomBarHeight //底部安全區距離,適用于全面屏下面有按鍵的 ScreenUtil.statusBarHeight //狀態欄高度 劉海屏會更高 ScreenUtil.textScaleFactor //系統字體縮放比例 ScreenUtil().scaleWidth // 實際寬度設計稿寬度的比例 ScreenUtil().scaleHeight // 實際高度與設計稿高度度的比例 ScreenUtil().orientation //屏幕方向 0.2.sw //屏幕寬度的0.2倍 0.5.sh //屏幕高度的50% 20.setVerticalSpacing // SizedBox(height: 20 * scaleHeight) 20.horizontalSpace // SizedBox(height: 20 * scaleWidth) const RPadding.all(8) // Padding.all(8.r) - 獲取到const的優點 REdgeInsts.all(8) // EdgeInsets.all(8.r) EdgeInsets.only(left:8,right:8).r // EdgeInsets.only(left:8.r,right:8.r).
適配字體
//輸入字體大小(單位與初始化時的單位相同) ScreenUtil().setSp(28) 28.sp //例子: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text( '16sp, 因為設置了`textScaleFactor`,不會隨系統變化.', style: TextStyle( color: Colors.black, fontSize: 16.sp, ), textScaleFactor: 1.0, ), Text( '16sp,如果未設置,我的字體大小將隨系統而變化.', style: TextStyle( color: Colors.black, fontSize: 16.sp, ), ), ], )
設置字體不隨系統字體大小進行改變 APP全局
MaterialApp( debugShowCheckedModeBanner: false, title: 'Flutter_ScreenUtil', theme: ThemeData( primarySwatch: Colors.blue, ), builder: (context, widget) { return MediaQuery( ///設置文字大小不隨系統設置改變 data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), child: widget, ); }, home: HomePage(title: 'FlutterScreenUtil Demo'), ),
單獨的Text:
Text("text", textScaleFactor: 1.0)
指定的小部件:
MediaQuery( // 如果這里context不可用,你可以新建一個 [Builder] 將 [MediaQuery] 放入其中 data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), child: AnyWidget(), )
總結:
本篇主要介紹了系統組價MediaQuery
的基本參數和基本使用情況,以及擴展第三方屏幕適配組件flutter_screenutil
.
原文鏈接:https://juejin.cn/post/7154686656707035150
相關推薦
- 2022-09-24 Go?類型轉化工具庫cast函數詳解_Golang
- 2022-11-29 C#中各種泛型集合的使用方法總結_C#教程
- 2022-07-19 C++調用Matplotlibcpp進行畫圖
- 2022-07-27 python如何查找列表中元素的位置_python
- 2023-04-11 Python中append淺拷貝機制詳解_python
- 2022-12-05 python如何在文件中部插入信息_python
- 2022-02-17 ERROR: but there is no HDFS_NAMENODE_USER defined.
- 2022-09-24 如何將一個CSV格式的文件分割成兩個CSV文件_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支