HarmonyOS Development with ArkUI Components - Media Query Implementation

1. Import Required Modules

import mediaquery from '@ohos.mediaquery';

2. Setting Up Media Query Conditions

Use the matchMediaSync interface to define media query conditions and store the returned listener handle. For example, to monitor landscape orientation changes:

const orientationListener = mediaquery.matchMediaSync('(orientation: landscape)');

Bind a callback fucntion to the listener handle. When the listener detects device state changes, it executes the callback function. Within the callback, you can modify page layouts or implement business logic based on different device states.

function handleOrientationChange(queryResult) {
  if (queryResult.matches) {
    // Execute when condition is met
  } else {
    // Execute when condition is not met
  }
}

orientationListener.on('change', handleOrientationChange);

3. Media Query Conditions

3.1 Syntax Rules

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

Example: screen and (device-type: tv) or (resolution < 2) represents a complex multi-condition query. The condition is satisfied when the device type is TV or the device resolution is less than 2.

3.2 Media Types

The screen media type matches screen devices including computer monitors, mobile device screens, and tablets. Using the screen media type allows applying different styles for various screen resolutions, optimizing responsive UI design.

Type Description
screen Media query based on screen-related parameters

3.3 Media Logic Operations

Logical operators (and, or, not, only) are used to construct complex media queries and can be combined using comma (,).

Keyword Description
and Applies multiple conditions simultaneously to the same rule
or Applies any of the multiple conditions to the rule
not Excludes certain conditions
only Specifies the device type for which the rule applies
comma (,) Combines different media queries to apply the same rule

Range operators (<=, >=, <, >) are used for comparing media conditions.

Operator Meaning Example
< Less than screen and (max-width: 768)
> Greater than screen and (min-width: 768)
<= Less then or equal screen and (max-height: 1024)
>= Greater than or equal screen and (min-height: 1024)

3.4 Media Features

Media features describe specific device attributes to apply differant styles for various viewports and screen sizes.

Feature Description
height Height of the application's drawable area
min-height Minimum height of the application's drawable area
max-height Maximum height of the application's drawable area
width Width of the application's drawable area
min-width Minimum width of the application's drawable area
max-width Maximum width of the application's drawable area
resolution Device resolution supporting dpi, dppx, and dpcm units
min-resolution Minimum device resolution
max-resolution Maximum device resolution
orientation Screen orientation (portrait or landscape)
device-height Device height
min-device-height Minimum device height
max-device-height Maximum device height
device-width Device width
device-type Device type (default, tablet)
min-device-width Minimum device width
max-device-width Maximum device width
round-screen True for circular screens, false otherwise
dark-mode True when system is in dark mode, false otherwise

4. Practical Examples

4.1 Stage Model Implementation

import mediaquery from '@ohos.mediaquery';
import window from '@ohos.window';
import common from '@ohos.app.ability.common';

let orientationCallback = null;

@Entry
@Component
struct ResponsiveLayoutDemo {
  @State textColor: string = '#DB7093';
  @State displayText: string = 'Portrait';
  
  // Listener for landscape orientation
  mediaListener = mediaquery.matchMediaSync('(orientation: landscape)');

  // Callback triggered when media query conditions change
  handleOrientationChange(result) {
    if (result.matches) { 
      this.textColor = '#FFD700';
      this.displayText = 'Landscape';
    } else {
      this.textColor = '#DB7093';
      this.displayText = 'Portrait';
    }
  }

  aboutToAppear() {
    // Bind component instance to callback
    orientationCallback = this.handleOrientationChange.bind(this);
    // Register callback function
    this.mediaListener.on('change', orientationCallback);
  }

  // Function to manually change device orientation
  private updateScreenOrientation(isLandscape: boolean) {
    const appContext = getContext(this) as common.UIAbilityContext;
    
    window.getLastWindow(appContext).then((currentWindow) => {
      currentWindow.setPreferredOrientation(
        isLandscape ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT
      );
    });
  }
  
  build() {
    Column({ space: 50 }) {
      Text(this.displayText)
        .fontSize(50)
        .fontColor(this.textColor)
        
      Text('Switch to Landscape')
        .fontSize(50)
        .fontColor(this.textColor)
        .backgroundColor(Color.Orange)
        .onClick(() => {
          this.updateScreenOrientation(true);
        })
        
      Text('Switch to Portrait')
        .fontSize(50)
        .fontColor(this.textColor)
        .backgroundColor(Color.Orange)
        .onClick(() => {
          this.updateScreenOrientation(false);
        })
    }
    .width('100%')
    .height('100%')
  }
}

4.2 FA Model Implementation

import mediaquery from '@ohos.mediaquery';
import featureAbility from '@ohos.ability.featureAbility';

let orientationHandler = null;

@Entry
@Component
struct MediaQueryDemo {
  @State elementColor: string = '#DB7093';
  @State labelText: string = 'Portrait';
  
  // Media query listener for landscape orientation
  queryListener = mediaquery.matchMediaSync('(orientation: landscape)');

  // Handle orientation changes
  processOrientation(result) {
    if (result.matches) {
      this.elementColor = '#FFD700';
      this.labelText = 'Landscape';
    } else {
      this.elementColor = '#DB7093';
      this.labelText = 'Portrait';
    }
  }

  aboutToAppear() {
    orientationHandler = this.processOrientation.bind(this);
    this.queryListener.on('change', orientationHandler);
  }

  build() {
    Column({ space: 50 }) {
      Text(this.labelText)
        .fontSize(50)
        .fontColor(this.elementColor)
    }
    .width('100%')
    .height('100%')
  }
}

Tags: HarmonyOS ArkUI Media Query Responsive Design UI Components

Posted on Thu, 17 Sep 2026 16:12:09 +0000 by Asperon