ui-ts-layout-mediaquery.md 9.7 KB
Newer Older
E
ester.zhou 已提交
1 2
# Media Query

E
ester.zhou 已提交
3
[Media queries](../reference/apis/js-apis-mediaquery.md) are at the core of responsive design and widely used on mobile devices. You can use them to create different application styles depending on the device type or device state. Specifically, media queries allow you to:
E
ester.zhou 已提交
4

E
ester.zhou 已提交
5
1. Design a layout style based on the device and application attributes (such as display area, dark light color, and resolution).
E
ester.zhou 已提交
6 7 8

2. Update the page layout to adapt to dynamic screen changes (for example, screen splitting or switching between landscape and portrait modes).

E
ester.zhou 已提交
9
   
E
ester.zhou 已提交
10 11 12 13 14

## Usage

Invoke the **mediaquery** API to set the media query condition and the callback, and change the page layout or implement service logic in the callback corresponding to the condition.

E
ester.zhou 已提交
15 16
First, import the **mediaquery** module, as shown below:

E
ester.zhou 已提交
17
```ts
E
ester.zhou 已提交
18
import mediaquery from '@ohos.mediaquery'
E
ester.zhou 已提交
19
```
E
ester.zhou 已提交
20

E
ester.zhou 已提交
21
Then, use the **matchMediaSync** API to set the media query condition and save the returned listener, as shown below:
E
ester.zhou 已提交
22

E
ester.zhou 已提交
23
```ts
E
ester.zhou 已提交
24
listener = mediaquery.matchMediaSync('(orientation: landscape)')
E
ester.zhou 已提交
25
```
E
ester.zhou 已提交
26 27 28

Finally, register the **onPortrait** callback using the saved listener, and change the page layout or implement service logic in the callback. When the media query condition is matched, the callback is triggered. The sample code is as follows:

E
ester.zhou 已提交
29
```ts
E
ester.zhou 已提交
30 31 32 33 34 35 36 37 38 39
onPortrait(mediaQueryResult) {
    if (mediaQueryResult.matches) {
        // do something here
    } else {
        // do something here
    }
}
listener.on('change', onPortrait)
```

E
ester.zhou 已提交
40 41 42 43 44 45
## Media Query Conditions

The media query condition consists of the media type (optional), logical operator, and media feature. The logical operator is used to connect different media types and media features. A media feature must be enclosed in parentheses (). There may be multiple media features. The specific rules are as follows:

### Syntax

E
ester.zhou 已提交
46 47 48
```
[media-type] [and|not|only] [(media-feature)]
```
E
ester.zhou 已提交
49

E
ester.zhou 已提交
50
Examples are as follows:
E
ester.zhou 已提交
51

E
ester.zhou 已提交
52
**screen and (round-screen: true)**: The query is valid when the device screen is round.
E
ester.zhou 已提交
53

E
ester.zhou 已提交
54
**(max-height: 800)**: The query is valid when the height is less than or equal to 800.
E
ester.zhou 已提交
55

E
ester.zhou 已提交
56
**(height <= 800)**: The query is valid when the height is less than or equal to 800.
E
ester.zhou 已提交
57

E
ester.zhou 已提交
58
**screen and (device-type: tv) or (resolution < 2)**: The query is valid when the device type is TV or the device resolution is less than 2. This is a multi-condition query that contains multiple media features.
E
ester.zhou 已提交
59 60 61

###  media-type

E
ester.zhou 已提交
62 63
| Type    | Description            |
| ------ | -------------- |
E
ester.zhou 已提交
64
| screen | Media query based on screen-related parameters.|
E
ester.zhou 已提交
65

E
ester.zhou 已提交
66
### Media Logic Operation (and|or|not|only)
E
ester.zhou 已提交
67 68 69

You can use logical operators (**and**, **or**, **not**, and **only**) to compose complex media queries. You can also combine them using comma (,). The following table describes the operators.

E
ester.zhou 已提交
70
  **Table 1** Media logical operators
E
ester.zhou 已提交
71

E
ester.zhou 已提交
72 73
| Type      | Description                                      |
| -------- | ---------------------------------------- |
E
ester.zhou 已提交
74 75 76 77 78
| and      | The **and** operator is used to combine multiple media features into one media query, in a logical AND operation. The query is valid only when all media features are true. It can also combine media types and media functions.<br>For example, **screen and (device-type: wearable) and (max-height: 600)** indicates that the query is valid when the device type is wearable and the maximum height of the application is 600 pixel units.|
| or       | The **or** operator is used to combine multiple media features into one media query, in a logical OR operation. The query is valid if a media feature is true.<br>For example, **screen and (max-height: 1000) or (round-screen: true)** indicates that the query is valid when the maximum height of the application is 1000 pixel units or the device screen is round.|
| not      | The **not** operator is used to perform a logical negation for a media query. **true** is returned if the query condition is not met. Otherwise, **false** is returned.<br>For example, **not screen and (min-height: 50) and (max-height: 600)** indicates that the query is valid when the height of the application is less than 50 pixel units or greater than 600 pixel units.<br>You must specify the media type when using the **not** operator.|
| only     | The **only** operator applies the selected style only when the entire expression is matched. It can be used to prevent ambiguity on browsers of earlier versions. The statements that contain both media types and media features produce ambiguity when they are received by some browsers of earlier versions. For example:<br>screen  and  (min-height:  50)<br>The browsers of earlier versions would mislead this sentence into screen, causing the fact that the specified style is applied when only the media type is matched. In this case, the **only** operator can be used to avoid this problem.<br>You must specify the media type when using the **only** operator.|
| , (comma) | The **or** operator is used to combine multiple media features into one media query, in a logical OR operation. The query is valid if a media feature is true. The effect of a comma operator is equivalent to that of the **or** operator.<br>For example, **screen and (min-height: 1000), (round-screen: true)** indicates that the query is valid when the minimum height of the application is 1000 pixel units or the device screen is round.|
E
ester.zhou 已提交
79

E
ester.zhou 已提交
80
At MediaQuery Level 4, range query is imported so that you can use the operators including &lt;=, &gt;=, &lt;, and &gt; besides the max- and min-operators.
E
ester.zhou 已提交
81

E
ester.zhou 已提交
82
  **Table 2** Logical operators for range query
E
ester.zhou 已提交
83

E
ester.zhou 已提交
84 85
| Type   | Description                                      |
| ----- | ---------------------------------------- |
E
ester.zhou 已提交
86 87 88 89
| &lt; = | Less than or equal to, for example, **screen and (50 &lt;= height)**.|
| &gt; = | Greater than or equal to, for example, **screen and (600 &gt;= height)**.|
| &lt; | Less than, for example, **screen and (50 &lt; height)**.|
| &gt; | Greater than, for example, **screen and (600 &gt; height)**.|
E
ester.zhou 已提交
90 91 92

### media-feature

E
ester.zhou 已提交
93 94 95 96 97 98 99 100
| Type             | Description                                                        |
| ----------------- | ------------------------------------------------------------ |
| height            | Height of the display area on the application page.               |
| min-height        | Minimum height of the display area on the application page.       |
| max-height        | Maximum height of the display area on the application page.       |
| width             | Width of the display area on the app page.                        |
| min-width         | Minimum width of the display area on the application page.        |
| max-width         | Maximum width of the display area on the application page.        |
E
ester.zhou 已提交
101
| resolution        | Resolution of the device. The unit can be dpi, dppx, or dpcm.<br>- **dpi** indicates the number of physical pixels per inch. 1 dpi ≈ 0.39 dpcm.<br>- **dpcm** indicates the number of physical pixels per centimeter. 1 dpcm ≈ 2.54 dpi.<br>- **dppx** indicates the number of physical pixels in each pixel. (This unit is calculated based on this formula: 96 px = 1 inch, which is different from the calculation method of the px unit on the page.) 1 dppx = 96 dpi.|
E
ester.zhou 已提交
102 103
| min-resolution    | Minimum device resolution.                                        |
| max-resolution    | Maximum device resolution.                                        |
E
ester.zhou 已提交
104
| orientation       | Screen orientation.<br>Options are as follows:<br>- orientation: portrait<br>- orientation: landscape|
E
ester.zhou 已提交
105 106 107 108 109 110 111
| device-height     | Height of the device.                                             |
| min-device-height | Minimum height of the device.                                     |
| max-device-height | Maximum height of the device.                                     |
| device-width      | Width of the device.                                              |
| min-device-width  | Minimum width of the device.                                      |
| max-device-width  | Maximum width of the device.                                      |
| device-type       | Type of the device.<br/>Value range: **default** |
E
ester.zhou 已提交
112
| round-screen      | Screen type. The value **true** means that the screen is round, and **false** means the opposite. |
E
ester.zhou 已提交
113
| dark-mode         | Whether the device is in dark mode. The value **true** means that the device is in dark mode, and **false** means the opposite.                       |
E
ester.zhou 已提交
114 115 116

## Example Scenario

E
ester.zhou 已提交
117
In the following example, media queries are used to apply different content and styles to the page text when the screen is switched between landscape and portrait modes.
E
ester.zhou 已提交
118

E
ester.zhou 已提交
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
```ts
import mediaquery from '@ohos.mediaquery'

let portraitFunc = null

@Entry
@Component
struct MediaQueryExample {
  @State color: string = '#DB7093'
  @State text: string = 'Portrait'
  listener = mediaquery.matchMediaSync('(orientation: landscape)') // The query is valid when the device is in landscape mode.

  onPortrait(mediaQueryResult) {
    if (mediaQueryResult.matches) {
      this.color = '#FFD700'
      this.text = 'Landscape'
    } else {
      this.color = '#DB7093'
      this.text = 'Portrait'
E
ester.zhou 已提交
138
    }
E
ester.zhou 已提交
139 140 141 142 143 144 145 146 147 148
  }

  aboutToAppear() {
    portraitFunc = this.onPortrait.bind(this) // Bind to the current application instance.
    this.listener.on('change', portraitFunc)
  }

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Text(this.text).fontSize(50).fontColor(this.color)
E
ester.zhou 已提交
149
    }
E
ester.zhou 已提交
150
    .width('100%').height('100%')
E
ester.zhou 已提交
151
  }
E
ester.zhou 已提交
152 153
}
```
E
ester.zhou 已提交
154 155 156

When the device is in landscape orientation, the text content is displayed in landscape mode in the color of #FFD700.

E
ester.zhou 已提交
157
![en-us_image_0000001262954829](figures/en-us_image_0000001262954829.png)
E
ester.zhou 已提交
158

E
ester.zhou 已提交
159 160 161
When the device is not in landscape orientation, the text content is displayed in portrait mode in the color of #DB7093.

![en-us_image_0000001263074739](figures/en-us_image_0000001263074739.png)