HarmonyOS todoList小案例

2023-12-25 10:52 姚铭强 498

HarmonyOS简介

  • HarmonyOS是一款面向万物互联时代的、全新的分布式操作系统。有三大系统特性,分别是:硬件互助,资源共享;一次开发,多端部署;统一OS,弹性部署。
  • HarmonyOS通过硬件互助,资源共享的能力,将多个形态不一的设备进行组网,共同构成一个超级终端,可在超级终端中实现任务分发与数据共享。
  • 硬件互助依赖HarmonyOS的分布式软总线,在此基础上,HarmonyOS还具备了分布式硬件虚拟化、分布式数据管理、分布式任务调度等分布式特性。

ArkTS

ArkTS是华为自研的开发语言。它在TypeScript(简称TS)的基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等相应的能力,让开发者以更简洁、更自然的方式开发跨端应用。

ArkUI

ArkUI是一套构建分布式应用界面的声明式UI开发框架。它使用极简的UI信息语法、丰富的UI组件、以及实时界面预览工具,提升开发效率。使用一套ArkTS API,就能在多个HarmonyOS设备上提供生动而流畅的用户界面体验。

搭建首页面

下方代码:

首先我们定义了一个State变量,State变量可以驱动页面的展示,并且类型为String,然后我们定义了一个Row,Row相当于flex布局中的横向布局,在Row里面定义了一个Column,而Column相当于flex中的纵向布局,然后我们添加了一个Text组件,给定样式字体大小为20,鸿蒙开发的时候像素单位为vp (屏幕密度相关像素,根据屏幕像素密度转换为屏幕物理像素),可以根据屏幕的大小自适应。

然后我们给Row一个高度,使其铺满整个屏幕,并且给予Row一个背景颜色,我们对背景颜色通过Es6模块化进行了一个简单的封装,如下图所示

最终,我们给整个页面添加了一个点击事件当页面进行点击的时候进行跳转,并且携带参数

import router from '@ohos.router'
import CommonConstant from '../common/CommonConstant'
@Entry
@Component
struct Index {
  @State message: string = 'HarmonyOs4.0基础知识完整项目'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
    .backgroundColor(CommonConstant.BACKGROUND)
    .onClick(()=>{
        router.pushUrl({
          url:'pages/todoList',
          params:{
            appName:'HarmonyOs4.0'
          }
        })
     })
  }
}

最终首页面效果图

当我们点击屏幕的时候会跳转到下一个页面

逻辑页面

在此页面我们首先获取路由参数,将其显示到页面上,然后我们使用 aboutToAppear 方法在组件出现时加载ES6模块封装的数据,然后赋值给 totalTasks 注意:当变量在组件内部的时候必须用this,当变量在组件外部的时候不能用this下图为封装的数据

然后我们添加了一个Text组件,再往下我们使用了forEach对封装的组件进行遍历,并将值通过父组件传递到子组件中,forEach的三个参数(数据、遍历的值、key值)

import router from '@ohos.router'
import TodoItem from '../view/TodoItem'

//路由参数获取
let appName= router.getParams()['appName']

//导入数据模型
import DataModel from '../viewData/DataModel'

//导入封装好的常量数据
import CommonConstant from '../common/CommonConstant'

@Entry
@Component
struct TodoList {
  @State message: string = appName
  // @State message: string = 'HarmonyOs4.0'
  //准备数组容器
  totalTasks: string[] = []

  //当组件加载完成build构建之前
  aboutToAppear() {
    //初始化数据
    this.totalTasks = DataModel.getData()
  }

  build() {
    Row() {
      Column({ space: 40 }) {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Divider()

        ForEach(this.totalTasks, item => {
          TodoItem({ content: item })
        }, item => JSON.stringify(item) //将任何数据变为字符串
        )


      }
      .width('100%')
    }
    .height('100%')
    .backgroundColor(CommonConstant.BACKGROUND)
  }
}

组件页面

我们通过定义与父组件相同的变量 content 接收父组件的值,并且运用了?来判断content的值,避免空值的时候报错,在下方的代码中我们使用了Row组件,让图片与文字放在一行展示,并且添加了点击事件,当点击的时候将 isDone 进行赋值,控制页面元素的切换,如图片的切换、透明度的切换等。

在下方代码中我们还定义了样式函数注意:样式函数@Extend()里面的值必须为组件值,并且定义的函数是可以传值的,通过对样式函数传递不同的值也能控制页面样式的变化

@Component
export default struct TodoItem {
  @State isDone: boolean = false
  content ?: string
  

  build() {
    Row({ space: 20 }) {
      if (this.isDone) {
        Image({r('app.media.todo')).TodoItem_img()
      } else {
        Image({r('app.media.untodo')).TodoItem_img()
      }
      Text(this.content)
        .fontSize(20)
        .decoration({ type: this.isDone ? TextDecorationType.LineThrough : TextDecorationType.None })
        .opacity(this.isDone ? 0.5 : 1)
    }.TodoItem_row()
    .onClick(() => {
      this.isDone = !this.isDone
    })

  }
}

//图片样式函数
@Extend(Image) function TodoItem_img() {
  .width(30)
  .height(30)
  .objectFit(ImageFit.Contain)
  .margin(20)
}

//扩展row样式函数
@Extend(Row) function TodoItem_row() {
  .width('90%')
  .height(50)
  .backgroundColor(Color.White)
  .borderRadius(25)
}

最终效果图