HarmonyOSNext_API16_媒体查询

媒体查询条件详解

媒体查询是响应式设计的核心工具,通过判断设备特征动态调整界面样式。其完整规则由媒体类型逻辑操作符媒体特征三部分组成,具体解析如下:


一、媒体查询语法结构

基本格式
[媒体类型] [逻辑操作符] (媒体特征)

  • 媒体类型:可选,默认screen(屏幕设备)。
  • 逻辑操作符:组合多个条件(如andor)。
  • 媒体特征:具体判断条件,用( )包裹。

示例

  • screen and (width >= 600px) → 屏幕设备且宽度≥600像素时生效。
  • (dark-mode: true) → 深色模式时生效(省略媒体类型,默认为screen)。

二、媒体类型(Media Type)
类型说明
screen屏幕设备(默认),如手机、平板、电脑。

规则

  • 若需指定非屏幕设备(如打印机),需显式声明(如print and (条件)
  • 未声明时,默认所有条件仅针对屏幕设备。

三、逻辑操作符(Logic Operators)

用于组合多个条件,形成复杂查询逻辑:

操作符作用示例
and所有条件同时满足时生效(width >= 600px) and (dark-mode: true) → 宽屏且深色模式生效。
or任一条件满足时生效(width < 300px) or (height < 300px) → 宽度或高度小于300像素时生效。
not否定整个条件(需搭配screennot screen and (device-type: tv) → 非电视设备时生效。
only兼容旧设备(实际效果等同screenonly screen and (width <= 500px) → 仅屏幕设备且宽度≤500像素时生效。
,等同or,但优先级更低(width >= 1000px), (device-type: tablet) → 宽屏或平板设备时生效。

注意事项

  • notonly必须与screen一起使用。
  • 逗号,优先级低于and,建议用括号明确逻辑分组。

四、范围操作符(Range Operators)

用于数值型媒体特征(如宽度、高度):

操作符说明示例
<=小于等于(height <= 800px)
>=大于等于(width >= 600vp)
<小于(resolution < 2dppx)
>大于(min-device-width > 720px)

五、媒体特征(Media Features)

定义具体判断条件,覆盖设备类型、屏幕状态、环境模式等:

1. 尺寸与方向
特征说明示例
width/height应用窗口的宽/高(支持vp/px(width >= 600vp) → 窗口宽度≥600虚拟像素。
min-width窗口最小宽度(min-width: 768px) → 窗口宽度≥768像素时生效。
orientation屏幕方向(portrait竖屏/landscape横屏)(orientation: landscape) → 横屏生效。
2. 设备属性
特征说明示例
device-type设备类型(如phonetablet(device-type: wearable) → 智能穿戴设备生效。
round-screen是否圆形屏幕(round-screen: true) → 圆形屏幕生效。
resolution设备分辨率(dpi/dppx/dpcm(resolution >= 300dpi) → 高分辨率设备生效。
3. 环境模式
特征说明示例
dark-mode深色模式(true/false(dark-mode: true) → 深色模式生效。
4. 特殊限制(鸿蒙系统)
  • 卡片中仅支持heightwidth
  • 设备宽度固定device-width在应用初始化后不更新(如折叠屏展开时不刷新)。

六、综合应用场景
  1. 横竖屏适配

  2. 深色模式适配

  3. 多设备适配


七、避坑指南
  1. 避免循环依赖

    • ❌ 错误:组件A依赖B的位置,B又依赖A → 布局无法计算。
  2. 动态内容更新

    • 组件尺寸变化时(如文字增多),需手动触发重排:
  3. 性能优化

    • 避免在媒体查询中频繁加载资源(如图片)。
    • 使用min-width/max-width替代固定宽度,增强灵活性。

import { mediaquery, window } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct MediaQueryExample {
  @State color: string = '#DB7093';
  @State text: string = 'Portrait';
  // 当设备横屏时条件成立
  listener:mediaquery.MediaQueryListener = this.getUIContext().getMediaQuery().matchMediaSync('(orientation: landscape)');

  // 当满足媒体查询条件时,触发回调
  onPortrait(mediaQueryResult:mediaquery.MediaQueryResult) {
    if (mediaQueryResult.matches as boolean) { // 若设备为横屏状态,更改相应的页面布局
      this.color = '#FFD700';
      this.text = 'Landscape';
    } else {
      this.color = '#DB7093';
      this.text = 'Portrait';
    }
  }

  aboutToAppear() {
    // 绑定当前应用实例
    // 绑定回调函数
    this.listener.on('change', (mediaQueryResult: mediaquery.MediaQueryResult) => {
      this.onPortrait(mediaQueryResult)
    });
  }

  aboutToDisappear() {
    // 解绑listener中注册的回调函数
    this.listener.off('change');
  }

  // 改变设备横竖屏状态函数
  private changeOrientation(isLandscape: boolean) {
    // 获取UIAbility实例的上下文信息
    let context:common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
    // 调用该接口手动改变设备横竖屏状态
    window.getLastWindow(context).then((lastWindow) => {
      lastWindow.setPreferredOrientation(isLandscape ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT)
    });
  }

  build() {
    Column({ space: 50 }) {
      Text(this.text).fontSize(50).fontColor(this.color)
      Text('Landscape').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
        .onClick(() => {
          this.changeOrientation(true);
        })
      Text('Portrait').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange)
        .onClick(() => {
          this.changeOrientation(false);
        })
    }
    .width('100%').height('100%')
  }
}

总结
媒体查询通过设备类型+逻辑符+特征条件的组合,实现“一码多端”的响应式适配。掌握其规则后,可高效适配不同设备尺寸、方向、主题模式,但需注意逻辑严谨性、性能优化和系统限制(如鸿蒙卡片仅支持宽高)。

### HarmonyOS Next 开发中首选项的使用与配置 #### 首选项概述 HarmonyOS Next 提供了用户首选项(Preferences)作为轻量级的数据持久化方案,适用于存储少量数据,例如用户的个性化设置或应用的配置信息[^3]。这些数据以键值对形式存储,其中键为字符串类型,而值可以是数字型、字符型、布尔型及其对应的数组类型。 #### 数据存储特点 - **轻量化设计**:由于所有数据会加载至内存中,因此不推荐存储大量数据集,以免造成过高的内存消耗。 - **快速访问**:得益于内存中的缓存机制,读取速度极快。 - **同步与异步操作支持**:开发者可以选择同步或异步的方式完成数据的读写操作。 - **多种数据类型支持**:除了基本数据类型外,还支持其数组形式的存储。 #### 示例代码展示 以下是基于 HarmonyOS Next 的 Preference 使用示例: ```typescript // 导入必要的模块 import preferences from '@ohos.data.preferences'; async function saveData() { try { // 创建一个名为 'userSettings' 的偏好对象实例 const pref = await preferences.getPreferences('userSettings'); // 同步保存数据 pref.putBoolean('isDarkMode', true); pref.putString('themeColor', '#FFFFFF'); pref.putInt('fontSize', 18); // 异步保存更改到磁盘 await pref.flush(); console.log('Data saved successfully.'); } catch (error) { console.error(`Error saving data: ${error}`); } } async function readData() { try { // 获取已创建的偏好对象实例 const pref = await preferences.getPreferences('userSettings'); // 同步读取数据 const isDarkModeEnabled = pref.getBoolean('isDarkMode', false); // 默认值为false const themeColor = pref.getString('themeColor', ''); // 默认值为空字符串 const fontSize = pref.getInt('fontSize', 14); // 默认值为14 console.log(`Dark Mode Enabled: ${isDarkModeEnabled}, Theme Color: ${themeColor}, Font Size: ${fontSize}`); } catch (error) { console.error(`Error reading data: ${error}`); } } ``` 上述代码展示了如何通过 `preferences` 模块实现数据的存储与读取功能[^2]。 #### 封装优化 为了提高代码可维护性和复用性,可以通过封装简化 Preference 的调用逻辑。以下是一个简单的封装示例: ```typescript class UserPreferenceManager { private static instance: UserPreferenceManager; private prefs: any; constructor(prefName: string) { this.initPrefs(prefName); } public static getInstance(prefName: string): UserPreferenceManager { if (!UserPreferenceManager.instance) { UserPreferenceManager.instance = new UserPreferenceManager(prefName); } return UserPreferenceManager.instance; } private async initPrefs(prefName: string) { this.prefs = await preferences.getPreferences(prefName); } public async put(key: string, value: any): Promise<void> { switch (typeof value) { case 'boolean': this.prefs.putBoolean(key, value as boolean); break; case 'number': this.prefs.putInt(key, value as number); break; case 'string': this.prefs.putString(key, value as string); break; default: throw new Error('Unsupported type for preference storage.'); } await this.prefs.flush(); // 确保数据立即保存到磁盘 } public get<T>(key: string, defaultValue?: T): T | undefined { const result = this.prefs.get(key, defaultValue); return typeof result === 'undefined' ? defaultValue : result; } } const userManager = UserPreferenceManager.getInstance('userSettings'); userManager.put('isDarkMode', true).then(() => console.log('Setting updated.')); console.log(userManager.get<boolean>('isDarkMode')); // 输出true ``` 此封装类实现了单例模式并提供了通用方法来管理 Preference 存储的操作。 #### 总结 HarmonyOS Next 中的用户首选项是一种高效便捷的小规模数据存储工具,适合于保存应用程序的状态和用户偏好的简单场景。通过合理利用同步/异步 API 和自定义封装,能够显著提升开发效率和代码质量。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值