媒體查詢(mediaquery)

2024-01-25 13:12 更新

概述

媒體查詢作為響應(yīng)式設(shè)計(jì)的核心,在移動(dòng)設(shè)備上應(yīng)用十分廣泛。媒體查詢可根據(jù)不同設(shè)備類型或同設(shè)備不同狀態(tài)修改應(yīng)用的樣式。媒體查詢常用于下面兩種場景:

  1. 針對(duì)設(shè)備和應(yīng)用的屬性信息(比如顯示區(qū)域、深淺色、分辨率),設(shè)計(jì)出相匹配的布局。
  2. 當(dāng)屏幕發(fā)生動(dòng)態(tài)改變時(shí)(比如分屏、橫豎屏切換),同步更新應(yīng)用的頁面布局。

引入與使用流程

媒體查詢通過mediaquery模塊接口,設(shè)置查詢條件并綁定回調(diào)函數(shù),在對(duì)應(yīng)的條件的回調(diào)函數(shù)里更改頁面布局或者實(shí)現(xiàn)業(yè)務(wù)邏輯,實(shí)現(xiàn)頁面的響應(yīng)式設(shè)計(jì)。具體步驟如下:

首先導(dǎo)入媒體查詢模塊。

  1. import mediaquery from '@ohos.mediaquery';

通過matchMediaSync接口設(shè)置媒體查詢條件,保存返回的條件監(jiān)聽句柄listener。例如監(jiān)聽橫屏事件:

  1. let listener = mediaquery.matchMediaSync('(orientation: landscape)');

給條件監(jiān)聽句柄listener綁定回調(diào)函數(shù)onPortrait,當(dāng)listener檢測(cè)設(shè)備狀態(tài)變化時(shí)執(zhí)行回調(diào)函數(shù)。在回調(diào)函數(shù)內(nèi),根據(jù)不同設(shè)備狀態(tài)更改頁面布局或者實(shí)現(xiàn)業(yè)務(wù)邏輯。

  1. onPortrait(mediaQueryResult) {
  2. if (mediaQueryResult.matches) {
  3. // do something here
  4. } else {
  5. // do something here
  6. }
  7. }
  8. listener.on('change', onPortrait);

媒體查詢條件

媒體查詢條件由媒體類型、邏輯操作符、媒體特征組成,其中媒體類型可省略,邏輯操作符用于連接不同媒體類型與媒體特征,其中,媒體特征要使用“()”包裹且可以有多個(gè)。具體規(guī)則如下:

語法規(guī)則

語法規(guī)則包括媒體類型(media-type)、媒體邏輯操作(media-logic-operations)媒體特征(media-feature)

  1. [media-type] [media-logic-operations] [(media-feature)]

例如:

  • screen and (round-screen: true) :表示當(dāng)設(shè)備屏幕是圓形時(shí)條件成立。
  • (max-height: 800) :表示當(dāng)高度小于等于800vp時(shí)條件成立。
  • (height <= 800) :表示當(dāng)高度小于等于800vp時(shí)條件成立。
  • screen and (device-type: tv) or (resolution < 2) :表示包含多個(gè)媒體特征的多條件復(fù)雜語句查詢,當(dāng)設(shè)備類型為tv或設(shè)備分辨率小于2時(shí)條件成立。

媒體類型(media-type)

類型

說明

screen

按屏幕相關(guān)參數(shù)進(jìn)行媒體查詢。

媒體邏輯操作(media-logic-operations)

媒體邏輯操作符:and、or、not、only用于構(gòu)成復(fù)雜媒體查詢,也可以通過comma(, )將其組合起來,詳細(xì)解釋說明如下表。

表1 媒體邏輯操作符

類型

說明

and

將多個(gè)媒體特征(Media Feature)以“與”的方式連接成一個(gè)媒體查詢,只有當(dāng)所有媒體特征都為true,查詢條件成立。另外,它還可以將媒體類型和媒體功能結(jié)合起來。例如:screen and (device-type: wearable) and (max-height: 600) 表示當(dāng)設(shè)備類型是智能穿戴且應(yīng)用的最大高度小于等于600個(gè)像素單位時(shí)成立。

or

將多個(gè)媒體特征以“或”的方式連接成一個(gè)媒體查詢,如果存在結(jié)果為true的媒體特征,則查詢條件成立。例如:screen and (max-height: 1000) or (round-screen: true) 表示當(dāng)應(yīng)用高度小于等于1000個(gè)像素單位或者設(shè)備屏幕是圓形時(shí),條件成立。

not

取反媒體查詢結(jié)果,媒體查詢結(jié)果不成立時(shí)返回true,否則返回false。例如:not screen and (min-height: 50) and (max-height: 600) 表示當(dāng)應(yīng)用高度小于50個(gè)像素單位或者大于600個(gè)像素單位時(shí)成立。

使用not運(yùn)算符時(shí)必須指定媒體類型。

only

當(dāng)整個(gè)表達(dá)式都匹配時(shí),才會(huì)應(yīng)用選擇的樣式,可以應(yīng)用在防止某些較早的版本的瀏覽器上產(chǎn)生歧義的場景。一些較早版本的瀏覽器對(duì)于同時(shí)包含了媒體類型和媒體特征的語句會(huì)產(chǎn)生歧義,比如:screen and (min-height: 50)。老版本瀏覽器會(huì)將這句話理解成screen,從而導(dǎo)致僅僅匹配到媒體類型(screen),就應(yīng)用了指定樣式,使用only可以很好地規(guī)避這種情況。

使用only時(shí)必須指定媒體類型。

comma(, )

將多個(gè)媒體特征以“或”的方式連接成一個(gè)媒體查詢,如果存在結(jié)果為true的媒體特征,則查詢條件成立。其效果等同于or運(yùn)算符。例如:screen and (min-height: 1000), (round-screen: true) 表示當(dāng)應(yīng)用高度大于等于1000個(gè)像素單位或者設(shè)備屏幕是圓形時(shí),條件成立。

媒體范圍操作符包括<=,>=,<,>,詳細(xì)解釋說明如下表。

表2 媒體邏輯范圍操作符

類型

說明

<=

小于等于,例如:screen and (height <= 50)。

>=

大于等于,例如:screen and (height >= 600)。

<

小于,例如:screen and (height < 50)。

>

大于,例如:screen and (height > 600)。

媒體特征(media-feature)

媒體特征包括應(yīng)用顯示區(qū)域的寬高、設(shè)備分辨率以及設(shè)備的寬高等屬性,詳細(xì)說明如下表。

表3 媒體特征說明表

類型

說明

height

應(yīng)用頁面可繪制區(qū)域的高度。

min-height

應(yīng)用頁面可繪制區(qū)域的最小高度。

max-height

應(yīng)用頁面可繪制區(qū)域的最大高度。

width

應(yīng)用頁面可繪制區(qū)域的寬度。

min-width

應(yīng)用頁面可繪制區(qū)域的最小寬度。

max-width

應(yīng)用頁面可繪制區(qū)域的最大寬度。

resolution

設(shè)備的分辨率,支持dpi,dppx和dpcm單位。其中:

- dpi表示每英寸中物理像素個(gè)數(shù),1dpi ≈ 0.39dpcm;

- dpcm表示每厘米上的物理像素個(gè)數(shù),1dpcm ≈ 2.54dpi;

- dppx表示每個(gè)px中的物理像素?cái)?shù)(此單位按96px = 1英寸為基準(zhǔn),與頁面中的px單位計(jì)算方式不同),1dppx = 96dpi。

min-resolution

設(shè)備的最小分辨率。

max-resolution

設(shè)備的最大分辨率。

orientation

屏幕的方向。

可選值:

- orientation: portrait(設(shè)備豎屏);

- orientation: landscape(設(shè)備橫屏)。

device-height

設(shè)備的高度。

min-device-height

設(shè)備的最小高度。

max-device-height

設(shè)備的最大高度。

device-width

設(shè)備的寬度。

device-type

設(shè)備的類型。

可選值:default、tablet。

min-device-width

設(shè)備的最小寬度。

max-device-width

設(shè)備的最大寬度。

round-screen

屏幕類型,圓形屏幕為true,非圓形屏幕為false。

dark-mode

系統(tǒng)為深色模式時(shí)為true,否則為false。

場景示例

下例中使用媒體查詢,實(shí)現(xiàn)屏幕橫豎屏切換時(shí),給頁面文本應(yīng)用添加不同的內(nèi)容和樣式。

Stage模型下的示例:

  1. import mediaquery from '@ohos.mediaquery';
  2. import window from '@ohos.window';
  3. import common from '@ohos.app.ability.common';
  4. let portraitFunc = null;
  5. @Entry
  6. @Component
  7. struct MediaQueryExample {
  8. @State color: string = '#DB7093';
  9. @State text: string = 'Portrait';
  10. // 當(dāng)設(shè)備橫屏?xí)r條件成立
  11. listener = mediaquery.matchMediaSync('(orientation: landscape)');
  12. // 當(dāng)滿足媒體查詢條件時(shí),觸發(fā)回調(diào)
  13. onPortrait(mediaQueryResult) {
  14. if (mediaQueryResult.matches) { // 若設(shè)備為橫屏狀態(tài),更改相應(yīng)的頁面布局
  15. this.color = '#FFD700';
  16. this.text = 'Landscape';
  17. } else {
  18. this.color = '#DB7093';
  19. this.text = 'Portrait';
  20. }
  21. }
  22. aboutToAppear() {
  23. // 綁定當(dāng)前應(yīng)用實(shí)例
  24. portraitFunc = this.onPortrait.bind(this);
  25. // 綁定回調(diào)函數(shù)
  26. this.listener.on('change', portraitFunc);
  27. }
  28. // 改變?cè)O(shè)備橫豎屏狀態(tài)函數(shù)
  29. private changeOrientation(isLandscape: boolean) {
  30. // 獲取UIAbility實(shí)例的上下文信息
  31. let context = getContext(this) as common.UIAbilityContext;
  32. // 調(diào)用該接口手動(dòng)改變?cè)O(shè)備橫豎屏狀態(tài)
  33. window.getLastWindow(context).then((lastWindow) => {
  34. lastWindow.setPreferredOrientation(isLandscape ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT)
  35. });
  36. }
  37. build() {
  38. Column({ space: 50 }) {
  39. Text(this.text).fontSize(50).fontColor(this.color)
  40. Text('Landscape').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
  41. .onClick(() => {
  42. this.changeOrientation(true);
  43. })
  44. Text('Portrait').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
  45. .onClick(() => {
  46. this.changeOrientation(false);
  47. })
  48. }
  49. .width('100%').height('100%')
  50. }
  51. }

FA模型下的示例:

  1. import mediaquery from '@ohos.mediaquery';
  2. import featureAbility from '@ohos.ability.featureAbility';
  3. let portraitFunc = null;
  4. @Entry
  5. @Component
  6. struct MediaQueryExample {
  7. @State color: string = '#DB7093';
  8. @State text: string = 'Portrait';
  9. listener = mediaquery.matchMediaSync('(orientation: landscape)'); // 當(dāng)設(shè)備橫屏?xí)r條件成立
  10. onPortrait(mediaQueryResult) { // 當(dāng)滿足媒體查詢條件時(shí),觸發(fā)回調(diào)
  11. if (mediaQueryResult.matches) { // 若設(shè)備為橫屏狀態(tài),更改相應(yīng)的頁面布局
  12. this.color = '#FFD700';
  13. this.text = 'Landscape';
  14. } else {
  15. this.color = '#DB7093';
  16. this.text = 'Portrait';
  17. }
  18. }
  19. aboutToAppear() {
  20. portraitFunc = this.onPortrait.bind(this); // 綁定當(dāng)前應(yīng)用實(shí)例
  21. this.listener.on('change', portraitFunc); //綁定回調(diào)函數(shù)
  22. }
  23. build() {
  24. Column({ space: 50 }) {
  25. Text(this.text).fontSize(50).fontColor(this.color)
  26. Text('Landscape').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
  27. .onClick(() => {
  28. let context = featureAbility.getContext();
  29. context.setDisplayOrientation(0); //調(diào)用該接口手動(dòng)改變?cè)O(shè)備橫豎屏狀態(tài)
  30. })
  31. Text('Portrait').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
  32. .onClick(() => {
  33. let context = featureAbility.getContext();
  34. context.setDisplayOrientation(1); //調(diào)用該接口手動(dòng)改變?cè)O(shè)備橫豎屏狀態(tài)
  35. })
  36. }
  37. .width('100%').height('100%')
  38. }
  39. }
圖1 豎屏
圖2 橫屏
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)