写点什么

鸿蒙智能家居【1.0】

作者:坚果
  • 2022 年 7 月 07 日
  • 本文字数:6453 字

    阅读完需:约 21 分钟

应用场景:

  • 智能家居。

今天打造的这一款全新智能家庭控制系统,凸显应用在智能控制和用户体验的特点,开创国内智能家居系统体验新局面。新的系统主要应用在鸿蒙生态。

在开始之前大家可以先预览一下我完成之后的效果。


是不是很炫酷呢?


搭建 OpenHarmony 环境

完成本篇 Codelab 我们首先要完成开发环境的搭建,本示例以 DaYu200 开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)

    以 3.0 版本为例:


  2. 搭建烧录环境

    完成DevEco Device Tool的安装

    完成Dayu200开发板的烧录

  3. 搭建开发环境

    开始前请参考工具准备 ,完成 DevEco Studio 的安装和开发环境配置。

    开发环境配置完成后,请参考使用工程向导 创建工程(模板选择“Empty Ability”),选择 eTS 语言开发。

    工程创建完成后,选择使用真机进行调测

相关概念

容器组件

基础组件

通用

TS语法糖

好的接下来我将详细讲解如何制作

开发教学

创建好的 eTS 工程目录

新建工程的 ETS 目录如下图所示。


各个文件夹和文件的作用:

  • index.ets:用于描述 UI 布局、样式、事件交互和页面逻辑。

  • app.ets:用于全局应用逻辑和应用生命周期管理。

  • pages:用于存放所有组件页面。

  • resources:用于存放资源配置文件。

接下来开始正文。

我们的主要操作都是在在 pages 目录中,然后我将用不到 10 分钟的时间,带大家实现这个功能。

拆解


根据设计图,我们可以分层展示,用 Column 包裹,大致分为这几步


可以看下本页的结构:


再详细一点:


import { SettingDetails } from './common/SettingDetails';import router from '@ohos.router';@Entry@Componentstruct Index {  @State title: string = '智能家居体验'  @State message: string = '你现在想要打开那些设置?'  @State desc: string = '点击所有适用的选项。这将帮助我们\n自定义您的主页'  @State Number: String[] = ['0', '1', '2', '3', '4']  @State private isSelect: boolean = true;  build() {      Column() {        Text(this.title)          .fontSize(80)          .fontWeight(FontWeight.Bold).onClick(() => {          router.push({ url: 'pages/SensorScreen' })        }).margin({ bottom: 60, top: 40 })        Text(this.message)          .fontSize(50)          .fontWeight(FontWeight.Bold).onClick(() => {          router.push({ url: 'pages/SensorScreen' })        }).margin({ bottom: 60 })        Text(this.desc)          .fontSize(30)          .textAlign(TextAlign.Center)          .fontWeight(FontWeight.Bold)          .onClick(() => {          })          .margin({ bottom: 60 })        Row() {          SettingDetails({            image: "common/images/setting.png",            title: "Maintenance\nRequests",            isSelected: this.isSelect!          })          SettingDetails({ image: "common/images/grain.png", title: "Integrations\n", isSelected: this.isSelect! })          SettingDetails({            image: "common/images/ic_highlight.png",            title: "Light\nControl",            isSelected: this.isSelect!          })        }        Row() {          SettingDetails({ image: "common/images/opacity.png", title: "Leak\nDetector", isSelected: this.isSelect! })          SettingDetails({            image: "common/images/ac_unit.png",            title: "Temperature\nControl",            isSelected: this.isSelect!          })          SettingDetails({ image: "common/images/key.png", title: "Guest\nAccess", isSelected: this.isSelect! })        }        Button("NEXT")          .fontSize(60)          .fontColor(Color.Black)          .width(600)          .height(100)          .backgroundColor(Color.Red)          .margin({ top: 100 })          .onClick(() => {            router.push({ url: 'pages/SensorScreen' })          })      }      .width('100%')        .height('100%').backgroundColor("#F5F5F5")  }}
复制代码


具体布局

具体布局设计到一些细节的地方,例如间隔,边框,当前组件尺寸设置等一些特殊情况,基本上就是嵌套,一层一层去实现。

代码结构


编码

Index.ets

import { SettingDetails } from './common/SettingDetails';import router from '@ohos.router';@Entry@Componentstruct Index {  @State title: string = '智能家居体验'  @State message: string = '你现在想要打开那些设置?'  @State desc: string = '点击所有适用的选项。这将帮助我们\n自定义您的主页'  @State Number: String[] = ['0', '1', '2', '3', '4']  @State private isSelect: boolean = true;  build() {      Column() {        Text(this.title)          .fontSize(80)          .fontWeight(FontWeight.Bold).onClick(() => {          router.push({ url: 'pages/SensorScreen' })        }).margin({ bottom: 60, top: 40 })        Text(this.message)          .fontSize(50)          .fontWeight(FontWeight.Bold).onClick(() => {          router.push({ url: 'pages/SensorScreen' })        }).margin({ bottom: 60 })        Text(this.desc)          .fontSize(30)          .textAlign(TextAlign.Center)          .fontWeight(FontWeight.Bold)          .onClick(() => {          })          .margin({ bottom: 60 })        Row() {          SettingDetails({            image: "common/images/setting.png",            title: "Maintenance\nRequests",            isSelected: this.isSelect!          })          SettingDetails({ image: "common/images/grain.png", title: "Integrations\n", isSelected: this.isSelect! })          SettingDetails({            image: "common/images/ic_highlight.png",            title: "Light\nControl",            isSelected: this.isSelect!          })        }        Row() {          SettingDetails({ image: "common/images/opacity.png", title: "Leak\nDetector", isSelected: this.isSelect! })          SettingDetails({            image: "common/images/ac_unit.png",            title: "Temperature\nControl",            isSelected: this.isSelect!          })          SettingDetails({ image: "common/images/key.png", title: "Guest\nAccess", isSelected: this.isSelect! })        }        Button("NEXT")          .fontSize(60)          .fontColor(Color.Black)          .width(600)          .height(100)          .backgroundColor(Color.Red)          .margin({ top: 100 })          .onClick(() => {            router.push({ url: 'pages/SensorScreen' })          })      }      .width('100%')    .height('100%').backgroundColor("#F5F5F5")  }}
复制代码


针对这一页:首先是头部


代码如下:

 Row() {        Image($r("app.media.logo"))          .objectFit(ImageFit.Contain)          .width(200)          .height(200)          .borderRadius(21)        Column() {          Text('June 14, 2022')            .fontSize(40).opacity(0.4)            .fontWeight(FontWeight.Bold)          Text('Good Morning,\nJianGuo',)            .fontSize(60)            .fontWeight(FontWeight.Bold)        }      }
复制代码


其次是个人信息,包括头像等信息:


代码如下:

复制代码


接下来就是温度和湿度


代码如下:

ow({ space: 120 }) {        Column() {          Text('40°',)            .fontSize(40).opacity(0.4)            .fontWeight(FontWeight.Bold)          Text('TEMPERATURE',)            .fontSize(40).opacity(0.4)        }.margin({ left: 60 })        Column() {          Text('59%',)            .fontSize(40).opacity(0.4)            .fontWeight(FontWeight.Bold)          Text('HUMIDITY',)            .fontSize(40).opacity(0.4)        }.margin({ right: 60 })      }.margin({ top: 20 })
复制代码


SensorScreen.ets

import { HomeDetails } from './common/homedetails';// second.etsimport router from '@ohos.router';@Entry@Componentstruct Second {  @State message: string = 'Hi there'  @State private isSelect: boolean = true;  build() {    Column() {      Row() {        Image($r("app.media.back"))          .objectFit(ImageFit.Contain)          .width(80)          .height(80)          .onClick(() => {            router.back()          })        Blank()        Text('Home')          .fontSize(45)          .fontWeight(FontWeight.Bold)        Blank()        Image($r("app.media.notifications_none"))          .objectFit(ImageFit.Contain)          .width(80)          .height(80)          .onClick(() => {            router.back()          })      }      .width('100%')      Row() {        Image($r("app.media.logo"))          .objectFit(ImageFit.Contain)          .width(200)          .height(200)          .borderRadius(21)        Column() {          Text('June 14, 2022')            .fontSize(40).opacity(0.4)            .fontWeight(FontWeight.Bold)          Text('Good Morning,\nJianGuo',)            .fontSize(60)            .fontWeight(FontWeight.Bold)        }      }      Row({ space: 120 }) {        Column() {          Text('40°',)            .fontSize(40).opacity(0.4)            .fontWeight(FontWeight.Bold)          Text('TEMPERATURE',)            .fontSize(40).opacity(0.4)        }.margin({ left: 60 })        Column() {          Text('59%',)            .fontSize(40).opacity(0.4)            .fontWeight(FontWeight.Bold)          Text('HUMIDITY',)            .fontSize(40).opacity(0.4)        }.margin({ right: 60 })      }.margin({ top: 20 })      Row() {        HomeDetails({})        HomeDetails({ image: "common/images/lightbull.png", isSelected: this.isSelect! })      }      Row() {        HomeDetails({ image: "common/images/opacity.png" })        HomeDetails({ image: "common/images/yytem0.png" })      }      Row(){       Column(){         Text('ADD',)           .fontSize(40).opacity(0.4)           .fontWeight(FontWeight.Bold)         Text('NEW CONTROL',)           .fontSize(40).opacity(0.4)       }       Blank()       Image($r("app.media.add"))         .objectFit(ImageFit.Contain)         .width(100)         .height(100)         .borderRadius(21).margin({right:40})      }.border({        color:Color.White,        width:8,        radius:20      }).width("88%").height(150)    }.width("100%")    .height('100%').backgroundColor("#F5F5F5")  }}
复制代码


我们可以对,下面的这块进行封装


代码如下

@Entry@Componentexport struct SettingDetails {  @State  private image: string = "common/images/setting.png"  @State  private title: string = "Maintenance\nRequests"  @State private isSelected: boolean = true;  build() {  Column() {    Image(this.image)      .objectFit(ImageFit.Contain)      .width(140)      .height(120)      .margin(20)      .border({        width: 12, color: this.isSelected ? Color.White : Color.Red,        radius: 20      })      .onClick(() => {        this.isSelected = !this.isSelected;      })    Text(this.title).fontSize(32).width(200).textAlign(TextAlign.Center)  }}}
复制代码

我们可以对,下面的这块进行封装


代码如下

@Entry@Componentexport struct SettingDetails {  @State  private image: string = "common/images/setting.png"  @State  private title: string = "Maintenance\nRequests"  @State private isSelected: boolean = true;  build() {  Column() {    Image(this.image)      .objectFit(ImageFit.Contain)      .width(140)      .height(120)      .margin(20)      .border({        width: 12, color: this.isSelected ? Color.White : Color.Red,        radius: 20      })      .onClick(() => {        this.isSelected = !this.isSelected;      })    Text(this.title).fontSize(32).width(200).textAlign(TextAlign.Center)  }}}
复制代码


最后就是底部


代码如下:

 Row(){       Column(){         Text('ADD',)           .fontSize(40).opacity(0.4)           .fontWeight(FontWeight.Bold)         Text('NEW CONTROL',)           .fontSize(40).opacity(0.4)       }       Blank()
Image($r("app.media.add")) .objectFit(ImageFit.Contain) .width(100) .height(100) .borderRadius(21).margin({right:40})
}.border({ color:Color.White, width:8, radius:20 }).width("88%").height(150)
复制代码


恭喜你

在本文中,通过实现智联汽车 App 示例,我主要为大家讲解了如下 ArkUI(基于 TS 扩展的类 Web 开发范式)组件,以及路由跳转。

容器组件

基础组件

通用

TS语法糖

希望通过本教程,各位开发者可以对以上基础组件具有更深刻的认识。

后面的计划:

  • 智能互联

  • 硬件交互

  • 动画交互

发布于: 18 小时前阅读数: 18
用户头像

坚果

关注

此间若无火炬,我便是唯一的光 2020.10.25 加入

公众号:“大前端之旅”,华为云享专家,InfoQ签约作者,51CTO博客首席体验官,专注于大前端技术的分享,包括Flutter,小程序,安卓,VUE,JavaScript。

评论

发布
暂无评论
鸿蒙智能家居【1.0】_HarmonyOS_坚果_InfoQ写作社区