项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star

效果演示

1. 概述

HarmonyOS NEXT应用开发中,一个常见的需求是根据不同设备类型(如手机、平板)提供不同的用户界面体验。本教程将详细讲解如何使用Row组件创建响应式图文导航项,实现在不同设备上的智能适配,提供最佳的用户体验。

2. 响应式设计的重要性

响应式设计是现代应用开发的核心理念之一,它能够让应用在不同尺寸和类型的设备上都能提供良好的用户体验。在HarmonyOS生态中,应用需要适配手机、平板、电视、穿戴设备等多种设备类型,这使得响应式设计变得尤为重要。

响应式导航项的设计考虑了以下几个方面:

  1. 空间利用:在小屏设备上(如手机)优先显示图标,节省空间;在大屏设备上(如平板)同时显示图标和文本,提供更丰富的信息。
  2. 交互体验:根据设备特性提供最适合的交互方式。
  3. 视觉一致性:在不同设备上保持品牌和设计语言的一致性。

3. 案例分析:响应式图文导航项

本案例展示了如何创建一个响应式的导航项,它能够根据设备类型自动调整其显示内容和布局。在手机上,它只显示图标;而在平板上,它同时显示图标和文本。

3.1 完整代码

import deviceInfo from '@ohos.deviceInfo';

@Component
export struct ResponsiveNavItem {
    @State isTablet: boolean = deviceInfo.deviceType !== 'PHONE'; // PHONE(手机)、TABLET(平板)、TV(电视)、WEARABLE(穿戴设备

    build() {
        Row({
            space: this.isTablet ? 8 : 0, // 平板显示间距,手机隐藏

        })
        {

            Image($r('app.media.01')) // 替换为实际图标
                .width(24)
                .height(24)
                .onClick(() => {
                    console.log('isTablet',deviceInfo.deviceType);
                })

            if (this.isTablet) { // 平板显示文字
                Text('首页')
                    .fontSize(14)
                    .margin({ left: 12 })
            }
        }
        .padding(12)
        .alignItems(VerticalAlign.Center)
        .backgroundColor(0xF5F5F5)
        .borderRadius(24)
    }
}

3.2 代码详解

3.2.1 导入设备信息模块

import deviceInfo from '@ohos.deviceInfo';

这行代码导入了HarmonyOS的设备信息模块,它提供了获取当前设备类型、型号等信息的能力。这是实现设备适配的基础。

3.2.2 组件声明与状态管理

@Component
export struct ResponsiveNavItem {
    @State isTablet: boolean = deviceInfo.deviceType !== 'PHONE'; // PHONE(手机)、TABLET(平板)、TV(电视)、WEARABLE(穿戴设备

这部分代码声明了一个名为ResponsiveNavItem的自定义组件,并使用@State装饰器定义了一个响应式状态变量isTablet。该变量通过判断deviceInfo.deviceType是否不等于'PHONE'来确定当前设备是否为平板。

deviceInfo.deviceType可能的值包括:

设备类型deviceType值说明
手机'PHONE'智能手机设备
平板'TABLET'平板电脑设备
电视'TV'智能电视设备
穿戴设备'WEARABLE'智能手表等穿戴设备

使用@State装饰器的好处是,当状态变量发生变化时,组件会自动重新渲染,确保UI与状态保持同步。

3.2.3 Row容器设置

Row({
    space: this.isTablet ? 8 : 0, // 平板显示间距,手机隐藏
})
{
    // 子组件
}
.padding(12)
.alignItems(VerticalAlign.Center)
.backgroundColor(0xF5F5F5)
.borderRadius(24)

这部分代码创建了一个Row容器,并根据设备类型动态设置了子组件之间的间距。在平板设备上,子组件间距为8vp;在手机设备上,间距为0。

Row容器的样式属性:

属性说明
padding12容器内边距为12vp
alignItemsVerticalAlign.Center子组件在垂直方向上居中对齐
backgroundColor0xF5F5F5背景色为浅灰色
borderRadius24边框圆角为24vp,呈现为胶囊形状

3.2.4 图标组件

Image($r('app.media.01')) // 替换为实际图标
    .width(24)
    .height(24)
    .onClick(() => {
        console.log('isTablet',deviceInfo.deviceType);
    })

这部分代码添加了一个图标组件,无论在什么设备上都会显示。图标的尺寸为24×24vp,并添加了点击事件,点击时会在控制台输出当前设备类型。

3.2.5 条件渲染文本

if (this.isTablet) { // 平板显示文字
    Text('首页')
        .fontSize(14)
        .margin({ left: 12 })
}

这部分代码使用条件渲染,只有在平板设备上才会显示文本组件。文本的字体大小为14fp,左边距为12vp,确保与图标之间有适当的间距。

4. 响应式设计的核心技术

4.1 设备类型检测

HarmonyOS提供了deviceInfo模块,可以获取当前设备的类型、屏幕尺寸等信息。在本案例中,我们使用deviceInfo.deviceType来检测设备类型。

@State isTablet: boolean = deviceInfo.deviceType !== 'PHONE';

除了设备类型,deviceInfo模块还提供了其他有用的信息:

属性说明示例值
deviceType设备类型'PHONE', 'TABLET', 'TV', 'WEARABLE'
manufacture设备制造商'HUAWEI'
brand设备品牌'HUAWEI'
marketName市场名称'Mate 40 Pro'
productSeries产品系列'Mate'
productModel产品型号'MAR-AL00'
softwareModel软件型号'MAR-AL00'
hardwareModel硬件型号'HWMAR'
hardwareProfile硬件配置信息'aarch64,aarch32'
serial设备序列号'0123456789ABCDEF'
bootloaderVersion引导程序版本'0.0.1'
abiListABI列表'arm64-v8a'
securityPatchTag安全补丁标签'2020-09-01'
displayVersion显示版本'HarmonyOS 3.0.0'
osReleaseType发布类型'Release'
osFullName操作系统完整名称'HarmonyOS 3.0.0'
majorVersion主版本号3
seniorVersion高版本号0
featureVersion特性版本号0
buildVersion构建版本号0
sdkApiVersionSDK API版本9
firstApiVersion首个API版本1
versionId版本ID'3.0.0'

4.2 条件渲染

条件渲染是响应式设计的关键技术之一,它允许我们根据不同条件显示不同的UI元素。在ArkTS中,可以使用if语句实现条件渲染:

if (this.isTablet) {
    Text('首页')
        .fontSize(14)
        .margin({ left: 12 })
}

除了if语句,还可以使用三元运算符在属性中实现条件逻辑:

space: this.isTablet ? 8 : 0

4.3 弹性空间处理

在响应式设计中,合理处理弹性空间是提供良好用户体验的关键。在本案例中,我们通过以下方式处理弹性空间:

  1. 动态间距:根据设备类型设置不同的间距

    space: this.isTablet ? 8 : 0
  2. 条件显示元素:在空间充足时显示更多信息

    if (this.isTablet) { // 平板显示文字
        Text('首页')
    }
  3. 统一的内边距:无论设备类型如何,保持一致的内边距确保视觉舒适

    .padding(12)

5. 实现要点与技巧

5.1 设备适配策略

在HarmonyOS应用开发中,可以采用以下设备适配策略:

  1. 基于设备类型适配:如本案例所示,根据设备类型(手机、平板等)提供不同的UI布局。
  2. 基于屏幕尺寸适配:根据屏幕尺寸动态调整UI元素的大小和布局。

    // 示例:基于屏幕宽度适配
    import window from '@ohos.window';
    
    let currentWindow = window.getLastWindow(getContext(this));
    let properties = currentWindow.getWindowProperties();
    let screenWidth = properties.windowRect.width;
    
    // 根据屏幕宽度设置不同的样式
    let fontSize = screenWidth > 600 ? 16 : 14;
  3. 基于方向适配:根据设备的横竖屏方向提供不同的布局。

    // 示例:监听屏幕方向变化
    import window from '@ohos.window';
    
    @State isLandscape: boolean = false;
    
    aboutToAppear() {
      let currentWindow = window.getLastWindow(getContext(this));
      currentWindow.on('windowSizeChange', () => {
        let properties = currentWindow.getWindowProperties();
        this.isLandscape = properties.windowRect.width > properties.windowRect.height;
      });
    }

5.2 组件复用与扩展

本案例中的ResponsiveNavItem组件设计得非常灵活,可以通过以下方式进行扩展:

  1. 添加属性自定义:可以添加属性来自定义图标、文本和样式。
@Component
export struct ResponsiveNavItem {
    icon: Resource;               // 图标资源
    text: string;                // 文本内容
    backgroundColor?: Color;     // 可选背景色
    @State isTablet: boolean = deviceInfo.deviceType !== 'PHONE';
    
    build() {
        Row({
            space: this.isTablet ? 8 : 0,
        })
        {
            Image(this.icon)
                .width(24)
                .height(24)
                
            if (this.isTablet) {
                Text(this.text)
                    .fontSize(14)
                    .margin({ left: 12 })
            }
        }
        .padding(12)
        .alignItems(VerticalAlign.Center)
        .backgroundColor(this.backgroundColor || 0xF5F5F5)
        .borderRadius(24)
    }
}
  1. 添加事件回调:可以添加点击事件回调,使组件更具交互性。
@Component
export struct ResponsiveNavItem {
    // ... 其他属性
    onItemClick?: () => void;    // 点击事件回调
    
    build() {
        Row({
            space: this.isTablet ? 8 : 0,
        })
        {
            // ... 子组件
        }
        .padding(12)
        .alignItems(VerticalAlign.Center)
        .backgroundColor(0xF5F5F5)
        .borderRadius(24)
        .onClick(() => {
            if (this.onItemClick) {
                this.onItemClick();
            }
        })
    }
}

5.3 样式优化技巧

为了使导航项在不同设备上都有良好的视觉效果,可以考虑以下样式优化技巧:

  1. 使用相对单位:使用vp(视口像素)和fp(字体像素)等相对单位,而不是固定像素值。
  2. 考虑触摸区域:确保触摸区域足够大,特别是在小屏设备上。一般建议触摸区域至少为44×44vp。
  3. 视觉反馈:添加点击状态的视觉反馈,提升用户体验。
.stateStyles({
    pressed: {
        backgroundColor: 0xE0E0E0,
        scale: 0.95
    }
})
  1. 无障碍支持:添加无障碍标签,使应用对所有用户都友好。
.accessibilityGroup(true)
.accessibilityText('导航到首页')

6. 实际应用场景

响应式导航项在实际应用中有广泛的应用场景:

6.1 底部导航栏

在应用的底部导航栏中,可以使用多个ResponsiveNavItem组件来创建导航选项。在手机上显示为图标,在平板上显示为图标+文本。

Column() {
    // 应用主内容
    Flex({ direction: FlexDirection.Column }) {
        // 主内容区域
    }.layoutWeight(1)
    
    // 底部导航栏
    Row() {
        ResponsiveNavItem(/* 首页导航项 */)
        ResponsiveNavItem(/* 分类导航项 */)
        ResponsiveNavItem(/* 消息导航项 */)
        ResponsiveNavItem(/* 我的导航项 */)
    }
    .width('100%')
    .justifyContent(FlexAlign.SpaceEvenly)
    .padding({ top: 8, bottom: 8 })
    .backgroundColor(0xFFFFFF)
}

6.2 侧边导航菜单

在具有侧边导航菜单的应用中,可以使用ResponsiveNavItem组件创建菜单项。

Column() {
    // 侧边导航菜单
    Column() {
        ResponsiveNavItem(/* 首页导航项 */)
        ResponsiveNavItem(/* 设置导航项 */)
        ResponsiveNavItem(/* 帮助导航项 */)
    }
    .width(this.isTablet ? 200 : 80)
    .padding(16)
    .gap(12)
}

6.3 工具栏

在应用的工具栏中,可以使用ResponsiveNavItem组件创建工具按钮。

Row() {
    // 工具栏
    Row() {
        ResponsiveNavItem(/* 新建按钮 */)
        ResponsiveNavItem(/* 编辑按钮 */)
        ResponsiveNavItem(/* 删除按钮 */)
    }
    .padding(8)
    .gap(8)
    .justifyContent(FlexAlign.Start)
}

7. 总结

本教程详细讲解了如何使用HarmonyOS NEXT的Row组件创建响应式图文导航项,实现在不同设备上的智能适配。
注意本案例中的获取设备类型方案存在问题, 可选其他方案替代


全栈若城
1 声望2 粉丝