利用场景:

  • 智慧出行。

智能汽车是集环境感知、布局决策、多等级辅助驾驶等性能于一体的智能网联综合零碎,它集中使用了计算机、古代传感、信息交融、通信、人工智能及自动控制等技术,是典型的高新技术综合体。简略的说,智能汽车的呈现将逐渐放松车、手、眼,让开车,用车变得简略。这样的产品对有本儿不敢上路的人来说或者是大大的福音。

在南方冬天有点冷,这个时候,去车里,温度很低,给人一种不难受的感觉,那么有没有一种可能,就是能够通过手机App,实现对车内的一些状况的监测,答案是有的,明天做的这个App,就是这样一个App。

我要实现的性能次要有

  • 用户能够解锁任何车门,
  • 查看电池状态,
  • 管制空调温度,
  • 查看轮胎的气压。

在开始之前大家能够先预览一下我实现之后的成果。如下图所示:

是不是很炫酷呢?

搭建OpenHarmony环境

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

  1. 获取OpenHarmony零碎版本:规范零碎解决方案(二进制)

    以3.0版本为例:

  2. 搭建烧录环境

    1. 实现DevEco Device Tool的装置
    2. 实现Dayu200开发板的烧录
  3. 搭建开发环境

    1. 开始前请参考工具筹备 ,实现DevEco Studio的装置和开发环境配置。
    2. 开发环境配置实现后,请参考应用工程向导 创立工程(模板抉择“Empty Ability”),抉择eTS语言开发。
    3. 工程创立实现后,抉择应用真机进行调测 。

相干概念

容器组件

  • Column
  • Row
  • Stack

根底组件

  • Text
  • Button
  • Image
  • Navigation

通用

  • 边框设置
  • 尺寸设置
  • 点击管制
  • 布局束缚
  • 背景设置
  • 点击事件

TS语法糖

好的接下来我将具体解说如何制作

开发教学

创立好的 eTS工程目录

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

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

  • index.ets:用于形容UI布局、款式、事件交互和页面逻辑。
  • app.ets:用于全局应用逻辑和利用生命周期治理。
  • pages:用于寄存所有组件页面。
  • resources:用于寄存资源配置文件。

接下来开始注释。

咱们的次要操作都是在在pages目录中,而后我将用不到10分钟的工夫,带大家实现这个性能。

拆解

依据设计图,咱们能够分为内容展示区和菜单。

针对这一点,咱们能够用Navigation组件作为Page页面的根容器,通过属性设置来展现页面的题目、工具栏、菜单。

 Navigation() {      Column({ space: 20 }) {        if (this.index == 0)        DoorLook()        else if (this.index == 1)        Battery()        else if (this.index == 2)        Temp()        else if (this.index == 3)        Tyre()      }      .backgroundColor(Color.Black)      .justifyContent(FlexAlign.SpaceAround)      .alignItems(HorizontalAlign.Center)      .justifyContent(FlexAlign.Center)      .size({ width: '100%', height: '100%' })    }  .size({ width: '100%', height: '100%' })    .toolBar(this.toolbarWidget())    .hideToolBar(this.hideToolBar)    .hideTitleBar(this.hideTitleBar)

具体布局

具体布局设计到一些细节的中央,例如距离,边框,以后组件尺寸设置等一些非凡状况,基本上就是嵌套,一层一层去实现。

代码构造

编码

Index.ets

import Tyre from './tyre_page';import Temp from './temp_page';import Battery from './battery_page';import DoorLook from './door_lock_page';@Entry@Componentstruct ComponentTest {  @State index: number = 0; // 选项卡下标,默认为第一个  @State hideToolBar: boolean = false;  @State hideTitleBar: boolean = true;  private imageArray: string[] = ['app.media.Lock', 'app.media.Charge', 'app.media.Temp', 'app.media.Tyre',]; // 数据源  @Builder toolbarWidget() { // 通过builder自定义toolbar    Row() {      Column() {        Image( this.index==0?$r('app.media.lock'):$r('app.media.lock0') )          .size({ width: 36, height: 36 }).margin({ bottom: 4, top: 12 })      }      .alignItems(HorizontalAlign.Center)      .height('100%')      .layoutWeight(1)      .onClick(() => {        this.index = 0;      })      Column() {        Image(this.index==1?$r('app.media.battery'): $r("app.media.battery0"))          .size({ width: 36, height: 36 }).margin({ bottom: 4, top: 12 })      }      .alignItems(HorizontalAlign.Center)      .height('100%')      .layoutWeight(1)      .onClick(() => {        this.index = 1;      })      Column() {        Image(this.index==2?$r('app.media.yytemp'): $r('app.media.yytem0'))          .size({ width: 36, height: 36 }).margin({ bottom: 4, top: 12 })      }      .alignItems(HorizontalAlign.Center)      .height('100%')      .layoutWeight(1)      .onClick(() => {        this.index = 2;      })      Column() {        Image( this.index==3?$r('app.media.tyre'): $r('app.media.tyre0'))          .size({ width: 36, height: 36 }).margin({ bottom: 4, top: 12 })      }      .alignItems(HorizontalAlign.Center)      .height('100%')      .layoutWeight(1)      .onClick(() => {        this.index = 3;      })    }.backgroundColor(Color.Black)    .width('100%')    .height(66)  }  build() {    Navigation() {      Column({ space: 20 }) {        //依据索引展现对应内容å        if (this.index == 0)        DoorLook()        else if (this.index == 1)        Battery()        else if (this.index == 2)        Temp()        else if (this.index == 3)        Tyre()      }      .backgroundColor(Color.Black)      .justifyContent(FlexAlign.SpaceAround)      .alignItems(HorizontalAlign.Center)      .justifyContent(FlexAlign.Center)      .size({ width: '100%', height: '100%' })    }    .size({ width: '100%', height: '100%' })    .title("跟着坚果学OpenHarmony")    .toolBar(this.toolbarWidget())//自定义底部菜单栏    .hideToolBar(this.hideToolBar)    .hideTitleBar(this.hideTitleBar)    .menus([      {        value: "关",        icon: 'common/images/door_lock.svg',        action: () => {console.log("工具栏")        }      },      {        value: "开",        icon: 'common/images/door_unlock.svg',        action: () => {        }      }    ])  }}

成果演示:

车锁页

@Entry@Componentexport default struct DoorLook {  //车锁页  @State isRightDoorLock: boolean = false;  @State isLeftDoorLock: boolean = false;  @State isBonnetLock: boolean = false;  @State isTrunkLock: boolean = false;  build() {    Column() {      Stack() {        Image($r("app.media.Car"))          .width("100%")          .height("100%")          .objectFit(ImageFit.Contain)          .margin({ left: 20 })        Image($r("app.media.door_lock"))          .width(60).height(60).position({ x: 340, y: 50 })          .onClick(() => {          })        Image($r("app.media.door_unlock")).width(60).height(60).position({ x: 50, y: 600 })        Image($r("app.media.door_unlock")).width(60).height(60).position({ x: 640, y: 600 })        Image($r("app.media.door_unlock")).width(60).height(60).position({ x: 340, y: 920 })      }      .backgroundColor(Color.Black)      .width("100%")      .height("100%")    }  }}

成果演示:

电池页

@Entry@Componentexport default struct Battery {  //电池页  build() {    Column() {      Stack() {        Image($r("app.media.Car"))          .width("100%")          .height("80%")          .objectFit(ImageFit.Contain)          .margin({ left: 20, top: 150, bottom: 300 })        Text("220 mi").fontColor(Color.White).fontWeight(FontWeight.Bold).fontSize(79).position({ x: 260, y: 20 })        Text("62 %").fontColor(Color.White).fontWeight(FontWeight.Bold).fontSize(60).position({ x: 320, y: 90 })        Text("22 mi /hr").fontColor(Color.White).fontWeight(FontWeight.Bold).fontSize(45).position({ x: 20, y: 1000 })        Text("232 v").fontColor(Color.White).fontWeight(FontWeight.Bold).fontSize(45).position({ x: 550, y: 1000 })      }      .backgroundColor(Color.Black)      .width("100%")      .height("100%")    }  }}

成果演示:

空调页

@Entry@Componentexport default struct Temp {  //空调页  build() {    Column() {      Stack() {        Image($r("app.media.Car"))          .width("100%")          .height("100%")          .objectFit(ImageFit.Contain)          .position({ x: 268, y: 90 })          .margin({ left: 20 })        Image($r("app.media.Hot_glow_4"))          .width("90%")          .height("90%")          .objectFit(ImageFit.Contain)          .position({ x: 220, y: 90 })          .margin({ left: 20 })        Text("29" + "\u2103",).fontSize(90).fontColor(Color.Orange).position({ x: 90, y: 400 })        Image($r("app.media.arrow_drop_up"))          .width(60)          .height(60)          .position({ x: 120, y: 360 })        Image($r("app.media.arrow_drop_down"))          .width(60)          .height(60)          .position({ x: 120, y: 480 })        Image($r("app.media.cool")).width(60).height(60).position({ x: 20, y: 40 })        Image($r("app.media.heating"))          .width(60)          .height(60)          .position({ x: 80, y: 90 })          .borderRadius(7)          .margin({ right: 40 })        Column() {          Text("以后温度").fontSize(32).fontColor(Color.White).margin({ bottom: 20 })          Row({ space: 30 }) {            Column() {              Text("外面").fontSize(32).fontColor(Color.Orange)              Text("20" + "\u2103",).fontSize(32).fontColor(Color.White)            }            Column() {              Text("外边").fontSize(32).fontColor(Color.Yellow)              Text("35" + "\u2103",).fontSize(32).fontColor(Color.White)            }          }        }.position({ x: 20, y: 800 })      }      .backgroundColor(Color.Black)      .offset({        y: -20      })      .width("100%")      .height("100%")    }  }}

成果演示:

轮胎页

import { TyrePsiCard } from './tyre_psi_card'@Entry@Componentexport default struct Tyre {  //轮胎页  build() {    Column() {      Stack() {        Image($r("app.media.Car"))          .width("100%")          .height("80%")          .objectFit(ImageFit.Contain)          .margin({ left: 20 })        Image($r("app.media.FL_Tyre"))          .width("10%")          .height("10%")          .objectFit(ImageFit.Contain)          .position({ x: 180, y: 700 })        Image($r("app.media.FL_Tyre"))          .width("10%")          .height("10%")          .objectFit(ImageFit.Contain)          .position({ x: 500, y: 700 })        Image($r("app.media.FL_Tyre"))          .width("10%")          .height("10%")          .objectFit(ImageFit.Contain)          .position({ x: 500, y: 260 })        Image($r("app.media.FL_Tyre"))          .width("10%")          .height("10%")          .objectFit(ImageFit.Contain)          .position({ x: 180, y: 260 })        TyrePsiCard({ x: 60, y: 60, boardColor: Color.Blue })        TyrePsiCard({ x: 380, y: 60, boardColor: Color.Blue })        TyrePsiCard({ x: 60, y: 500, boardColor: Color.Blue, isBottomTwoTyre: false })        TyrePsiCard({ x: 380, y: 500, isBottomTwoTyre: false })      }      .backgroundColor(Color.Black)      .width("100%")      .height("100%")    }  }}

成果演示:

轮胎参数

/** * 轮胎详细信息 */@Entry@Componentexport struct TyrePsiCard {  private text: string = ''  private x: number = 0  private y: number = 0  private boardColor: Color = Color.Red  private isBottomTwoTyre: boolean = true;  build() {    Column() {      if (this.isBottomTwoTyre) {        Text("23.6psi",).fontSize(60)          .fontColor(Color.White).margin({ right: 60 })        Text("56.0\u2103").fontSize(36)          .fontColor(Color.Orange).margin({ bottom: 70 })        Text("Low").fontSize(60)          .fontColor(Color.White)        Text("Pressure").fontSize(36)          .fontColor(Color.White)      } else {        Text("Low").fontSize(60).margin({ right: 60 })          .fontColor(Color.White)        Text("Pressure").fontSize(36)          .fontColor(Color.White).margin({ bottom: 70 })        Text("23.6psi",).fontSize(60)          .fontColor(Color.White)        Text("56.0\u2103").fontSize(36)          .fontColor(Color.Orange)      }    }    .border({      width: 3,      color: this.boardColor    })    .width(280)    .justifyContent(FlexAlign.Start)    .alignItems(HorizontalAlign.Start)    //    .padding({ left: 10, bottom: 20, top: 20 })    .position({ x: this.x, y: this.y })  }}

成果演示:

祝贺你

在本文中,通过实现智联汽车App示例,我次要为大家解说了如下ArkUI(基于TS扩大的类Web开发范式)组件

容器组件

  • Column
  • Row
  • Stack

根底组件

  • Text
  • TextInput
  • Button
  • Image
  • Navigation

通用

  • 边框设置
  • 尺寸设置
  • 点击管制
  • 布局束缚
  • 背景设置
  • 点击事件

TS语法糖

心愿通过本教程,各位开发者能够对以上根底组件具备更粗浅的意识。

前面的打算:

  • 一键启动
  • 硬件交互
  • 动画交互