暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

73.[HarmonyOS NEXT 实战案例十一] 智能家居控制面板网格布局(上)

原创 若城 2025-06-07
140

[HarmonyOS NEXT 实战案例十一] 智能家居控制面板网格布局(上)

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

效果演示

1. 概述

本教程将详细讲解如何使用HarmonyOS NEXT中的GridRow和GridCol组件实现智能家居控制面板的网格布局。通过网格布局,我们可以创建一个直观、美观的智能家居控制界面,方便用户管理和控制家中的各种智能设备。

本教程将涵盖以下内容:

  • 智能设备数据结构设计
  • 数据准备
  • 整体布局实现
  • GridRow和GridCol组件配置
  • 设备卡片实现
  • 布局效果分析

2. 数据结构设计

首先,我们需要定义智能设备的数据结构,包含设备的基本信息:

// 智能设备类型 export interface DeviceType { id: number; // 设备ID name: string; // 设备名称 icon: Resource; // 设备图标 type: string; // 设备类型 room: string; // 所在房间 status: boolean; // 设备状态(开/关) value?: number; // 设备值(如亮度、温度等) color?: string; // 设备颜色(如灯光颜色) } // 房间类型 export interface RoomType { id: number; // 房间ID name: string; // 房间名称 icon: Resource; // 房间图标 deviceCount: number; // 设备数量 }

3. 数据准备

接下来,我们准备一些示例数据用于展示:

// 房间数据 private rooms: RoomType[] = [ { id: 1, name: '客厅', icon: $r('app.media.ic_living_room'), deviceCount: 5 }, { id: 2, name: '卧室', icon: $r('app.media.ic_bedroom'), deviceCount: 3 }, { id: 3, name: '厨房', icon: $r('app.media.ic_kitchen'), deviceCount: 4 }, { id: 4, name: '浴室', icon: $r('app.media.ic_bathroom'), deviceCount: 2 }, { id: 5, name: '书房', icon: $r('app.media.ic_study'), deviceCount: 3 } ]; // 智能设备数据 private devices: DeviceType[] = [ { id: 1, name: '客厅灯', icon: $r('app.media.ic_light'), type: 'light', room: '客厅', status: true, value: 80, color: '#FFD700' }, { id: 2, name: '空调', icon: $r('app.media.ic_ac'), type: 'ac', room: '客厅', status: true, value: 24 }, { id: 3, name: '电视', icon: $r('app.media.ic_tv'), type: 'tv', room: '客厅', status: false }, { id: 4, name: '窗帘', icon: $r('app.media.ic_curtain'), type: 'curtain', room: '客厅', status: true, value: 100 }, { id: 5, name: '音响', icon: $r('app.media.ic_speaker'), type: 'speaker', room: '客厅', status: false }, { id: 6, name: '卧室灯', icon: $r('app.media.ic_light'), type: 'light', room: '卧室', status: false, value: 0, color: '#FFFFFF' }, { id: 7, name: '床头灯', icon: $r('app.media.ic_bedside_lamp'), type: 'light', room: '卧室', status: true, value: 30, color: '#FFA07A' }, { id: 8, name: '卧室空调', icon: $r('app.media.ic_ac'), type: 'ac', room: '卧室', status: true, value: 26 }, { id: 9, name: '厨房灯', icon: $r('app.media.ic_light'), type: 'light', room: '厨房', status: false, value: 0, color: '#FFFFFF' }, { id: 10, name: '冰箱', icon: $r('app.media.ic_fridge'), type: 'fridge', room: '厨房', status: true, value: 4 }, { id: 11, name: '烤箱', icon: $r('app.media.ic_oven'), type: 'oven', room: '厨房', status: false }, { id: 12, name: '洗碗机', icon: $r('app.media.ic_dishwasher'), type: 'dishwasher', room: '厨房', status: false }, { id: 13, name: '浴室灯', icon: $r('app.media.ic_light'), type: 'light', room: '浴室', status: false, value: 0, color: '#FFFFFF' }, { id: 14, name: '热水器', icon: $r('app.media.ic_water_heater'), type: 'water_heater', room: '浴室', status: true, value: 45 }, { id: 15, name: '书房灯', icon: $r('app.media.ic_light'), type: 'light', room: '书房', status: true, value: 70, color: '#F5F5DC' }, { id: 16, name: '台灯', icon: $r('app.media.ic_desk_lamp'), type: 'light', room: '书房', status: true, value: 50, color: '#F0E68C' }, { id: 17, name: '书房空调', icon: $r('app.media.ic_ac'), type: 'ac', room: '书房', status: false, value: 0 } ];

4. 布局实现

4.1 整体布局结构

我们将使用Column作为最外层容器,包含顶部状态栏、房间选择栏和设备网格列表:

build() { Column() { // 顶部状态栏 this.StatusBar() // 房间选择栏 this.RoomSelector() // 设备网格列表 this.DeviceGrid() } .width('100%') .height('100%') .backgroundColor('#F5F5F5') }

4.2 顶部状态栏

@Builder private StatusBar() { Row() { Column() { Text('智能家居') .fontSize(20) .fontWeight(FontWeight.Bold) .fontColor('#333333') Text('欢迎回家,张先生') .fontSize(14) .fontColor('#666666') .margin({ top: 4 }) } .alignItems(HorizontalAlign.Start) Blank() Row() { // 添加设备按钮 Button({ type: ButtonType.Circle }) { Image($r('app.media.ic_add')) .width(24) .height(24) } .width(40) .height(40) .backgroundColor('#EEEEEE') .margin({ right: 12 }) // 设置按钮 Button({ type: ButtonType.Circle }) { Image($r('app.media.ic_settings')) .width(24) .height(24) } .width(40) .height(40) .backgroundColor('#EEEEEE') } } .width('100%') .padding({ left: 16, right: 16, top: 16, bottom: 16 }) .backgroundColor(Color.White) }

4.3 房间选择栏

@State currentRoom: string = '全部'; @Builder private RoomSelector() { Scroll(ScrollDirection.Horizontal) { Row() { // 全部选项 Column() { Image($r('app.media.ic_all_rooms')) .width(40) .height(40) .margin({ bottom: 8 }) Text('全部') .fontSize(14) .fontColor(this.currentRoom === '全部' ? '#4285F4' : '#666666') .fontWeight(this.currentRoom === '全部' ? FontWeight.Bold : FontWeight.Normal) } .width(80) .height(80) .padding(8) .margin({ right: 12 }) .borderRadius(12) .backgroundColor(this.currentRoom === '全部' ? '#E8F0FE' : Color.White) .onClick(() => { this.currentRoom = '全部'; }) // 各个房间选项 ForEach(this.rooms, (room: RoomType) => { Column() { Image(room.icon) .width(40) .height(40) .margin({ bottom: 8 }) Text(room.name) .fontSize(14) .fontColor(this.currentRoom === room.name ? '#4285F4' : '#666666') .fontWeight(this.currentRoom === room.name ? FontWeight.Bold : FontWeight.Normal) } .width(80) .height(80) .padding(8) .margin({ right: 12 }) .borderRadius(12) .backgroundColor(this.currentRoom === room.name ? '#E8F0FE' : Color.White) .onClick(() => { this.currentRoom = room.name; }) }) } .padding({ left: 16, right: 16 }) } .scrollBar(BarState.Off) .width('100%') .margin({ top: 16, bottom: 16 }) }

4.4 设备网格列表

这是本教程的核心部分,我们使用GridRow和GridCol组件实现设备网格列表:

@Builder private DeviceGrid() { Column() { // 标题栏 Row() { Text(this.currentRoom === '全部' ? '所有设备' : `${this.currentRoom}设备`) .fontSize(18) .fontWeight(FontWeight.Bold) .fontColor('#333333') Blank() Text(`${this.getFilteredDevices().length}个设备`) .fontSize(14) .fontColor('#666666') } .width('100%') .padding({ left: 16, right: 16, bottom: 12 }) // 使用GridRow和GridCol实现网格布局 Scroll() { GridRow({ columns: { xs: 2, sm: 2, md: 3, lg: 4 }, gutter: { x: 16, y: 16 } }) { ForEach(this.getFilteredDevices(), (device: DeviceType) => { GridCol() { this.DeviceCard(device) } }) } .width('100%') .padding(16) } .scrollBar(BarState.Off) .scrollable(ScrollDirection.Vertical) .width('100%') .layoutWeight(1) } .width('100%') .layoutWeight(1) .backgroundColor('#F5F5F5') .borderRadius({ topLeft: 24, topRight: 24 }) }

4.5 设备卡片实现

@Builder private DeviceCard(device: DeviceType) { Column() { // 设备图标和状态 Row() { Image(device.icon) .width(24) .height(24) .fillColor(device.status ? '#4285F4' : '#999999') Blank() Toggle({ type: ToggleType.Switch, isOn: device.status }) .width(40) .height(24) .selectedColor('#4285F4') .onChange((isOn: boolean) => { this.toggleDevice(device.id, isOn); }) } .width('100%') // 设备名称 Text(device.name) .fontSize(16) .fontWeight(FontWeight.Medium) .fontColor('#333333') .margin({ top: 12 }) // 设备状态文本 Text(this.getDeviceStatusText(device)) .fontSize(14) .fontColor('#666666') .margin({ top: 4 }) // 设备控制组件(根据设备类型显示不同控制) if (device.type === 'light' && device.status) { // 灯光亮度控制 Column() { Row() { Image($r('app.media.ic_brightness')) .width(16) .height(16) .margin({ right: 8 }) Text('亮度') .fontSize(14) .fontColor('#666666') Blank() Text(`${device.value}%`) .fontSize(14) .fontColor('#4285F4') } .width('100%') .margin({ top: 12 }) Slider({ value: device.value, min: 0, max: 100, step: 1, style: SliderStyle.OutSet }) .width('100%') .margin({ top: 8 }) .selectedColor('#4285F4') .onChange((value: number) => { this.updateDeviceValue(device.id, value); }) } .width('100%') } else if (device.type === 'ac' && device.status) { // 空调温度控制 Row() { Button('-') .width(32) .height(32) .fontSize(16) .fontColor('#666666') .backgroundColor('#EEEEEE') .borderRadius(16) .onClick(() => { if (device.value > 16) { this.updateDeviceValue(device.id, device.value - 1); } }) Text(`${device.value}°C`) .fontSize(16) .fontColor('#4285F4') .fontWeight(FontWeight.Bold) .margin({ left: 12, right: 12 }) Button('+') .width(32) .height(32) .fontSize(16) .fontColor('#666666') .backgroundColor('#EEEEEE') .borderRadius(16) .onClick(() => { if (device.value < 30) { this.updateDeviceValue(device.id, device.value + 1); } }) } .width('100%') .margin({ top: 12 }) .justifyContent(FlexAlign.Center) } } .width('100%') .padding(16) .backgroundColor(Color.White) .borderRadius(16) .onClick(() => { this.showDeviceDetail(device); }) }

4.6 辅助方法

// 获取当前房间的设备列表 private getFilteredDevices(): DeviceType[] { if (this.currentRoom === '全部') { return this.devices; } else { return this.devices.filter(device => device.room === this.currentRoom); } } // 切换设备状态 private toggleDevice(deviceId: number, status: boolean): void { const index = this.devices.findIndex(device => device.id === deviceId); if (index !== -1) { this.devices[index].status = status; } } // 更新设备值 private updateDeviceValue(deviceId: number, value: number): void { const index = this.devices.findIndex(device => device.id === deviceId); if (index !== -1) { this.devices[index].value = value; } } // 获取设备状态文本 private getDeviceStatusText(device: DeviceType): string { if (!device.status) { return '已关闭'; } switch (device.type) { case 'light': return `亮度 ${device.value}%`; case 'ac': return `温度 ${device.value}°C`; case 'curtain': return `开启度 ${device.value}%`; case 'fridge': return `温度 ${device.value}°C`; case 'water_heater': return `温度 ${device.value}°C`; default: return '已开启'; } } // 显示设备详情 private showDeviceDetail(device: DeviceType): void { // 在实际应用中,这里会跳转到设备详情页面 console.info(`显示设备详情:${device.name}`); }

5. GridRow和GridCol配置详解

在本案例中,我们使用了GridRow和GridCol组件实现网格布局。下面详细解析其配置:

5.1 GridRow配置

GridRow({ columns: { xs: 2, sm: 2, md: 3, lg: 4 }, gutter: { x: 16, y: 16 } })
  • columns:定义不同屏幕尺寸下的列数

    • xs: 2:极小屏幕(如小型手机)显示2列
    • sm: 2:小屏幕(如大型手机)显示2列
    • md: 3:中等屏幕(如平板)显示3列
    • lg: 4:大屏幕(如桌面)显示4列
  • gutter:定义网格间的间距

    • x: 16:水平间距为16像素
    • y: 16:垂直间距为16像素

5.2 GridCol配置

在本案例中,我们使用了默认的GridCol配置,没有指定span属性,这意味着每个设备卡片占据一个网格单元。

GridCol() { this.DeviceCard(device) }

如果需要某些设备卡片占据更多的空间,可以通过span属性进行配置:

GridCol({ span: { xs: 2, sm: 1, md: 1, lg: 1 } }) { this.DeviceCard(device) }

这样配置后,在极小屏幕(xs)上,该设备卡片会占据2列,而在其他屏幕尺寸上占据1列。

6. 布局效果分析

6.1 响应式布局

通过GridRow的columns配置,我们实现了响应式布局,使应用能够适应不同屏幕尺寸的设备:

屏幕尺寸 列数 效果
极小屏幕(xs) 2列 每行显示2个设备卡片
小屏幕(sm) 2列 每行显示2个设备卡片
中等屏幕(md) 3列 每行显示3个设备卡片
大屏幕(lg) 4列 每行显示4个设备卡片

6.2 网格间距

通过GridRow的gutter配置,我们设置了网格间的间距为16像素,使布局更加美观、清晰。

6.3 设备卡片设计

我们设计的设备卡片包含以下元素:

  1. 设备图标和开关:显示设备类型和当前状态,用户可以直接切换设备的开关状态
  2. 设备名称:清晰地显示设备的名称
  3. 设备状态文本:显示设备的当前状态,如亮度、温度等
  4. 设备控制组件:根据设备类型显示不同的控制组件,如灯光的亮度滑块、空调的温度控制按钮等

这种设计使用户能够快速了解设备状态,并进行简单的控制操作。

7. GridRow和GridCol组件详解

7.1 GridRow组件

GridRow是HarmonyOS NEXT提供的网格行容器组件,用于创建网格布局。它具有以下主要属性:

属性 类型 描述
columns number | { xs?: number, sm?: number, md?: number, lg?: number, xl?: number, xxl?: number } 当前行的总列数
gutter number | { x?: number, y?: number } 栅格间隔
breakpoints { value: number, reference: BreakpointsReference }[] 自定义断点值

7.2 GridCol组件

GridCol是HarmonyOS NEXT提供的网格列容器组件,用于在GridRow中创建网格列。它具有以下主要属性:

属性 类型 描述
span number | { xs?: number, sm?: number, md?: number, lg?: number, xl?: number, xxl?: number } 列宽度
offset number | { xs?: number, sm?: number, md?: number, lg?: number, xl?: number, xxl?: number } 列偏移量
order number | { xs?: number, sm?: number, md?: number, lg?: number, xl?: number, xxl?: number } 列顺序

8. 完整代码

@Entry @Component struct SmartHomeGrid { // 智能设备类型 interface DeviceType { id: number; // 设备ID name: string; // 设备名称 icon: Resource; // 设备图标 type: string; // 设备类型 room: string; // 所在房间 status: boolean; // 设备状态(开/关) value?: number; // 设备值(如亮度、温度等) color?: string; // 设备颜色(如灯光颜色) } // 房间类型 interface RoomType { id: number; // 房间ID name: string; // 房间名称 icon: Resource; // 房间图标 deviceCount: number; // 设备数量 } // 房间数据 private rooms: RoomType[] = [ { id: 1, name: '客厅', icon: $r('app.media.ic_living_room'), deviceCount: 5 }, { id: 2, name: '卧室', icon: $r('app.media.ic_bedroom'), deviceCount: 3 }, { id: 3, name: '厨房', icon: $r('app.media.ic_kitchen'), deviceCount: 4 }, { id: 4, name: '浴室', icon: $r('app.media.ic_bathroom'), deviceCount: 2 }, { id: 5, name: '书房', icon: $r('app.media.ic_study'), deviceCount: 3 } ]; // 智能设备数据 @State devices: DeviceType[] = [ { id: 1, name: '客厅灯', icon: $r('app.media.ic_light'), type: 'light', room: '客厅', status: true, value: 80, color: '#FFD700' }, { id: 2, name: '空调', icon: $r('app.media.ic_ac'), type: 'ac', room: '客厅', status: true, value: 24 }, { id: 3, name: '电视', icon: $r('app.media.ic_tv'), type: 'tv', room: '客厅', status: false }, { id: 4, name: '窗帘', icon: $r('app.media.ic_curtain'), type: 'curtain', room: '客厅', status: true, value: 100 }, { id: 5, name: '音响', icon: $r('app.media.ic_speaker'), type: 'speaker', room: '客厅', status: false }, { id: 6, name: '卧室灯', icon: $r('app.media.ic_light'), type: 'light', room: '卧室', status: false, value: 0, color: '#FFFFFF' }, { id: 7, name: '床头灯', icon: $r('app.media.ic_bedside_lamp'), type: 'light', room: '卧室', status: true, value: 30, color: '#FFA07A' }, { id: 8, name: '卧室空调', icon: $r('app.media.ic_ac'), type: 'ac', room: '卧室', status: true, value: 26 }, { id: 9, name: '厨房灯', icon: $r('app.media.ic_light'), type: 'light', room: '厨房', status: false, value: 0, color: '#FFFFFF' }, { id: 10, name: '冰箱', icon: $r('app.media.ic_fridge'), type: 'fridge', room: '厨房', status: true, value: 4 }, { id: 11, name: '烤箱', icon: $r('app.media.ic_oven'), type: 'oven', room: '厨房', status: false }, { id: 12, name: '洗碗机', icon: $r('app.media.ic_dishwasher'), type: 'dishwasher', room: '厨房', status: false }, { id: 13, name: '浴室灯', icon: $r('app.media.ic_light'), type: 'light', room: '浴室', status: false, value: 0, color: '#FFFFFF' }, { id: 14, name: '热水器', icon: $r('app.media.ic_water_heater'), type: 'water_heater', room: '浴室', status: true, value: 45 }, { id: 15, name: '书房灯', icon: $r('app.media.ic_light'), type: 'light', room: '书房', status: true, value: 70, color: '#F5F5DC' }, { id: 16, name: '台灯', icon: $r('app.media.ic_desk_lamp'), type: 'light', room: '书房', status: true, value: 50, color: '#F0E68C' }, { id: 17, name: '书房空调', icon: $r('app.media.ic_ac'), type: 'ac', room: '书房', status: false, value: 0 } ]; @State currentRoom: string = '全部'; build() { Column() { // 顶部状态栏 this.StatusBar() // 房间选择栏 this.RoomSelector() // 设备网格列表 this.DeviceGrid() } .width('100%') .height('100%') .backgroundColor('#F5F5F5') } @Builder private StatusBar() { Row() { Column() { Text('智能家居') .fontSize(20) .fontWeight(FontWeight.Bold) .fontColor('#333333') Text('欢迎回家,张先生') .fontSize(14) .fontColor('#666666') .margin({ top: 4 }) } .alignItems(HorizontalAlign.Start) Blank() Row() { // 添加设备按钮 Button({ type: ButtonType.Circle }) { Image($r('app.media.ic_add')) .width(24) .height(24) } .width(40) .height(40) .backgroundColor('#EEEEEE') .margin({ right: 12 }) // 设置按钮 Button({ type: ButtonType.Circle }) { Image($r('app.media.ic_settings')) .width(24) .height(24) } .width(40) .height(40) .backgroundColor('#EEEEEE') } } .width('100%') .padding({ left: 16, right: 16, top: 16, bottom: 16 }) .backgroundColor(Color.White) } @Builder private RoomSelector() { Scroll(ScrollDirection.Horizontal) { Row() { // 全部选项 Column() { Image($r('app.media.ic_all_rooms')) .width(40) .height(40) .margin({ bottom: 8 }) Text('全部') .fontSize(14) .fontColor(this.currentRoom === '全部' ? '#4285F4' : '#666666') .fontWeight(this.currentRoom === '全部' ? FontWeight.Bold : FontWeight.Normal) } .width(80) .height(80) .padding(8) .margin({ right: 12 }) .borderRadius(12) .backgroundColor(this.currentRoom === '全部' ? '#E8F0FE' : Color.White) .onClick(() => { this.currentRoom = '全部'; }) // 各个房间选项 ForEach(this.rooms, (room: RoomType) => { Column() { Image(room.icon) .width(40) .height(40) .margin({ bottom: 8 }) Text(room.name) .fontSize(14) .fontColor(this.currentRoom === room.name ? '#4285F4' : '#666666') .fontWeight(this.currentRoom === room.name ? FontWeight.Bold : FontWeight.Normal) } .width(80) .height(80) .padding(8) .margin({ right: 12 }) .borderRadius(12) .backgroundColor(this.currentRoom === room.name ? '#E8F0FE' : Color.White) .onClick(() => { this.currentRoom = room.name; }) }) } .padding({ left: 16, right: 16 }) } .scrollBar(BarState.Off) .width('100%') .margin({ top: 16, bottom: 16 }) } @Builder private DeviceGrid() { Column() { // 标题栏 Row() { Text(this.currentRoom === '全部' ? '所有设备' : `${this.currentRoom}设备`) .fontSize(18) .fontWeight(FontWeight.Bold) .fontColor('#333333') Blank() Text(`${this.getFilteredDevices().length}个设备`) .fontSize(14) .fontColor('#666666') } .width('100%') .padding({ left: 16, right: 16, bottom: 12 }) // 使用GridRow和GridCol实现网格布局 Scroll() { GridRow({ columns: { xs: 2, sm: 2, md: 3, lg: 4 }, gutter: { x: 16, y: 16 } }) { ForEach(this.getFilteredDevices(), (device: DeviceType) => { GridCol() { this.DeviceCard(device) } }) } .width('100%') .padding(16) } .scrollBar(BarState.Off) .scrollable(ScrollDirection.Vertical) .width('100%') .layoutWeight(1) } .width('100%') .layoutWeight(1) .backgroundColor('#F5F5F5') .borderRadius({ topLeft: 24, topRight: 24 }) } @Builder private DeviceCard(device: DeviceType) { Column() { // 设备图标和状态 Row() { Image(device.icon) .width(24) .height(24) .fillColor(device.status ? '#4285F4' : '#999999') Blank() Toggle({ type: ToggleType.Switch, isOn: device.status }) .width(40) .height(24) .selectedColor('#4285F4') .onChange((isOn: boolean) => { this.toggleDevice(device.id, isOn); }) } .width('100%') // 设备名称 Text(device.name) .fontSize(16) .fontWeight(FontWeight.Medium) .fontColor('#333333') .margin({ top: 12 }) // 设备状态文本 Text(this.getDeviceStatusText(device)) .fontSize(14) .fontColor('#666666') .margin({ top: 4 }) // 设备控制组件(根据设备类型显示不同控制) if (device.type === 'light' && device.status) { // 灯光亮度控制 Column() { Row() { Image($r('app.media.ic_brightness')) .width(16) .height(16) .margin({ right: 8 }) Text('亮度') .fontSize(14) .fontColor('#666666') Blank() Text(`${device.value}%`) .fontSize(14) .fontColor('#4285F4') } .width('100%') .margin({ top: 12 }) Slider({ value: device.value, min: 0, max: 100, step: 1, style: SliderStyle.OutSet }) .width('100%') .margin({ top: 8 }) .selectedColor('#4285F4') .onChange((value: number) => { this.updateDeviceValue(device.id, value); }) } .width('100%') } else if (device.type === 'ac' && device.status) { // 空调温度控制 Row() { Button('-') .width(32) .height(32) .fontSize(16) .fontColor('#666666') .backgroundColor('#EEEEEE') .borderRadius(16) .onClick(() => { if (device.value > 16) { this.updateDeviceValue(device.id, device.value - 1); } }) Text(`${device.value}°C`) .fontSize(16) .fontColor('#4285F4') .fontWeight(FontWeight.Bold) .margin({ left: 12, right: 12 }) Button('+') .width(32) .height(32) .fontSize(16) .fontColor('#666666') .backgroundColor('#EEEEEE') .borderRadius(16) .onClick(() => { if (device.value < 30) { this.updateDeviceValue(device.id, device.value + 1); } }) } .width('100%') .margin({ top: 12 }) .justifyContent(FlexAlign.Center) } } .width('100%') .padding(16) .backgroundColor(Color.White) .borderRadius(16) .onClick(() => { this.showDeviceDetail(device); }) } // 获取当前房间的设备列表 private getFilteredDevices(): DeviceType[] { if (this.currentRoom === '全部') { return this.devices; } else { return this.devices.filter(device => device.room === this.currentRoom); } } // 切换设备状态 private toggleDevice(deviceId: number, status: boolean): void { const index = this.devices.findIndex(device => device.id === deviceId); if (index !== -1) { this.devices[index].status = status; } } // 更新设备值 private updateDeviceValue(deviceId: number, value: number): void { const index = this.devices.findIndex(device => device.id === deviceId); if (index !== -1) { this.devices[index].value = value; } } // 获取设备状态文本 private getDeviceStatusText(device: DeviceType): string { if (!device.status) { return '已关闭'; } switch (device.type) { case 'light': return `亮度 ${device.value}%`; case 'ac': return `温度 ${device.value}°C`; case 'curtain': return `开启度 ${device.value}%`; case 'fridge': return `温度 ${device.value}°C`; case 'water_heater': return `温度 ${device.value}°C`; default: return '已开启'; } } // 显示设备详情 private showDeviceDetail(device: DeviceType): void { // 在实际应用中,这里会跳转到设备详情页面 console.info(`显示设备详情:${device.name}`); } }

9. 总结

本教程详细讲解了如何使用HarmonyOS NEXT中的GridRow和GridCol组件实现智能家居控制面板的网格布局。通过合理的数据结构设计、精心的UI设计和灵活的GridRow配置,我们实现了一个美观、响应式的智能家居控制面板。

主要内容包括:

  • 智能设备数据结构设计和数据准备
  • 整体布局实现,包括顶部状态栏、房间选择栏和设备网格列表
  • GridRow和GridCol组件的配置和使用
  • 设备卡片的设计和实现,包括不同类型设备的控制组件
  • 布局效果分析
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论