??????當我們同時為手機和平板適配編寫 app 針對不同屏幕尺寸進行 UI 布局或當用戶偏好設(shè)置較大字號或是想要最大限度等減少動畫等摊腋;此時就需要 MediaQuery 來幫我們獲取所用設(shè)備的信息以及用戶設(shè)置的偏好信息;
MediaQuery
??????MediaQuery 一直存在于 WidgetsApp 和 MaterialApp 中工禾,MediaQuery 繼承自 InheritedWidget 是一個單獨的 Widget锉走,但一般通過 MediaQuery.of(context) 來獲取相關(guān)信息缀旁;
??????當相關(guān)信息發(fā)生變化觅丰,例如屏幕旋轉(zhuǎn)等時翰铡,屏幕中 Widget 會重新構(gòu)建钝域,以保持最新狀態(tài);我們可以通過 MediaQuery 構(gòu)造函數(shù)和提供的靜態(tài)方法手動設(shè)置對應(yīng)的相關(guān)信息锭魔;
1. MediaQuery()
const MediaQuery({
Key key,
@required this.data,
@required Widget child,
})
2. MediaQuery.removePadding() 刪除內(nèi)邊距
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() 刪除視圖內(nèi)邊距
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 包含關(guān)于媒介的相關(guān)信息例证;一般通過 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 為像素密度;與設(shè)備物理像素有關(guān)笙蒙,與橫豎屏等無關(guān)抵屿;
print('屏幕像素比 -> ${MediaQuery.of(context).devicePixelRatio}');
3. orientation
??????orientation 為橫豎屏,Orientation.landscape 為橫屏手趣,Orientation.portrait 為豎屏晌该;
print('橫豎屏 -> ${MediaQuery.of(context).orientation}');
4. textScaleFactor
??????textScaleFactor 為
每個邏輯像素的字體像素數(shù),小菜理解為字體的像素比绿渣;注意朝群,小菜設(shè)置了默認字體像素密度為標準的 1.2 倍之后調(diào)整設(shè)備系統(tǒng)字號,其 1.2 倍依舊是以標準字號為基礎(chǔ)擴大 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 為當前設(shè)備的亮度模式姜胖;注意調(diào)整屏幕亮度并不會改變該模式,與當前系統(tǒng)支持的黑暗模式和明亮模式相關(guān)淀散;
print('亮度模式 -> ${MediaQuery.of(context).platformBrightness}');
6. alwaysUse24HourFormat
??????alwaysUse24HourFormat 為當前設(shè)備是否為 24 小時制右莱;
print('24 小時制 -> ${MediaQuery.of(context).alwaysUse24HourFormat}');
7. accessibleNavigation
??????accessibleNavigation 為是否使用 TalkBack 或 VoiceOver 之類的輔助功能與應(yīng)用程序進行交互,用以輔助視力障礙人群档插;
print('亮度模式 -> ${MediaQuery.of(context).accessibleNavigation}');
8. invertColors
??????invertColors 為是否使用顏色反轉(zhuǎn)慢蜓,主要用于 iOS 設(shè)備;
print('顏色反轉(zhuǎn) -> ${MediaQuery.of(context).invertColors}');
9. highContrast
??????highContrast 為用戶是否要求前景與背景之間的對比度高郭膛,主要用于 iOS 設(shè)備晨抡;
print('前后背景高對比度 -> ${MediaQuery.of(context).highContrast}');
10. disableAnimations
??????disableAnimations 為平臺是否要求禁用或減少動畫;
print('是否減少動畫 -> ${MediaQuery.of(context).disableAnimations}');
11. boldText
??????boldText 為平臺是否要求使用粗體则剃;
print('是否使用粗體 -> ${MediaQuery.of(context).boldText}');
12. padding
??????padding 為屏幕內(nèi)邊距耘柱,一般是劉海兒屏或異形屏中被系統(tǒng)遮擋部分邊距;
print('內(nèi)邊距 -> ${MediaQuery.of(context).padding}');
13. viewInsets
??????viewInsets 為鍵盤彈出時等遮擋屏幕邊距棍现,其中 viewInsets.bottom 為鍵盤高度调煎;
print('鍵盤遮擋內(nèi)邊距 -> ${MediaQuery.of(context).viewInsets}');
14. systemGestureInsets
??????systemGestureInsets 為手勢邊距,如 Android Q 之后添加的向左滑動關(guān)閉頁面等己肮;
print('系統(tǒng)手勢邊距 -> ${MediaQuery.of(context).systemGestureInsets}');
15. viewPadding
??????viewPadding 小菜理解為視圖內(nèi)邊距士袄,為屏幕被劉海兒屏或異形屏中被系統(tǒng)遮擋部分,從 MediaQuery 邊界的邊緣計算谎僻;此值是保持不變窖剑;例如,屏幕底部的軟件鍵盤可能會覆蓋并占用需要底部填充的相同區(qū)域戈稿,因此不會影響此值西土;
print('系統(tǒng)手勢邊距 -> ${MediaQuery.of(context).systemGestureInsets}');
16. physicalDepth
??????physicalDepth 為設(shè)備物理層級,小菜暫時還未想到對應(yīng)的應(yīng)用場景鞍盗;
print('設(shè)備物理層級 -> ${MediaQuery.of(context).physicalDepth}');
Tips
??????小菜在嘗試獲取其他子 Widget Size 時需了,有兩點需要注意跳昼,首先要設(shè)置一個全局的 GlobalKey 來獲取當前位置,key 需要為唯一的肋乍;第二通過 GlobalKey().currentContext 獲取 BuildContext 上下文環(huán)境鹅颊,從而獲取對應(yīng)尺寸;
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 的應(yīng)用和理解還不夠深入墓造;如有錯誤請多多指導堪伍!
來源: 阿策小和尚