我的任务清单

本篇案例介绍如何使用ArkTS声明式语法和基础组件,实现简易待办列表。效果为点击某一事项,替换标签图片、虚化文字。

1. 案例效果截图

2. 案例运用到的知识点

2.1. 核心知识点

  • Text组件:显示一段文本的组件。
  • Column组件:沿垂直方向布局的容器。
  • Row组件:沿水平方向布局的容器。

2.2. 其他知识点

  • ArkTS 语言基础
  • 自定义组件和组件生命周期
  • 内置组件:Column/Text/Row/Stack/Blank/Button
  • 日志管理类的编写
  • 常量与资源分类的访问
  • MVVM模式

3. 代码结构

├──entry/src/main/ets                  // ArkTS代码区
│  ├──common
│  │  └──constants
│  │     └──CommonConstants.ets   // 公共常量类
│  ├──entryability
│  │  └──EntryAbility.ets             // 程序入口类
│  ├──pages
│  │  └──ToDoListPage.ets           // 主页面
│  ├──view
│  │  └──ToDoItem.ets              // 自定义单项待办组件
│  └──viewmodel
│     └──DataModel.ets              // 列表数据获取文件
└──entry/src/main/resources	         // 资源文件目录

4. 公共文件与资源

本案例涉及到的常量类和工具类代码如下:

  1. 通用常量类
// entry/src/main/ets/common/constants/CommonConstant.ets
export default class CommonConstants {
  static readonly FULL_LENGTH: string = '100%'
  static readonly TITLE_WIDTH: string = '80%'
  static readonly LIST_DEFAULT_WIDTH: string = '93.3%'
  static readonly OPACITY_DEFAULT: number = 1
  static readonly OPACITY_COMPLETED: number = 0.4
  static readonly BORDER_RADIUS: number = 24
  static readonly FONT_WEIGHT: number = 500
  static readonly COLUMN_SPACE: number = 16
  static readonly TODO_DATA: Array<string> = [
    "看完1000本书",
    "一次无计划的旅程",
    "高空跳伞",
    "拿到驾照",
    "献血",
    "拥有自己的房子",
    "创业(无论成败)",
    "亲手种出食物并吃掉"
  ]
}

本案例涉及到的资源文件如下:

4.1. string.json

// entry/src/main/resources/base/element/string.json
{
  "string": [
    {
      "name": "module_desc",
      "value": "module description"
    },
    {
      "name": "EntryAbility_desc",
      "value": "description"
    },
    {
      "name": "EntryAbility_label",
      "value": "清单列表"
    },
    {
      "name": "page_title",
      "value": "我的清单"
    }
  ]
}

4.2. float.json

// entry/src/main/resources/base/element/float.json
{
  "float": [
    {
      "name": "checkbox_width",
      "value": "28vp"
    },
    {
      "name": "checkbox_margin",
      "value": "20vp"
    },
    {
      "name": "item_font_size",
      "value": "20fp"
    },
    {
      "name": "title_font_size",
      "value": "28fp"
    },
    {
      "name": "title_font_height",
      "value": "33vp"
    },
    {
      "name": "title_margin_top",
      "value": "24vp"
    },
    {
      "name": "title_margin_bottom",
      "value": "12vp"
    },
    {
      "name": "list_item_height",
      "value": "64vp"
    }
  ]
}

其他资源请到源码中获取。

5. 功能实现

5.1. 首页逻辑

// entry/src/main/ets/pages/ToDoListPage.ets
import DataModel from '../viewmodel/DataModel'
import CommonConstants from '../common/constant/CommonConstant'
import ToDoItem from '../view/ToDoItem'

@Entry
@Component
struct ToDoListPage {
  private totalTasks: Array<string> = []

  aboutToAppear() {
    this.totalTasks = DataModel.getData()
  }

  build() {
    Column({ space: CommonConstants.COLUMN_SPACE }) {
      Text($r('app.string.page_title'))
        .fontSize($r('app.float.title_font_size'))
        .fontWeight(FontWeight.Bold)
        .lineHeight($r('app.float.title_font_height'))
        .width(CommonConstants.TITLE_WIDTH)
        .margin({
          top: $r('app.float.title_margin_top'),
          bottom: $r('app.float.title_margin_bottom')
        })
        .textAlign(TextAlign.Start)

      ForEach(this.totalTasks, (item: string) => {
        ToDoItem({ content: item })
      }, (item: string) => JSON.stringify(item))
    }
    .width(CommonConstants.FULL_LENGTH)
    .height(CommonConstants.FULL_LENGTH)
    .backgroundColor($r('app.color.page_background'))
  }
}

5.2. 数据源获取

// entry/src/main/ets/viewmodel/DataModel.ets
import CommonConstants from '../common/constant/CommonConstant'

export class DataModel {

  private tasks: Array<string> = CommonConstants.TODO_DATA

  getData(): Array<string> {
    return this.tasks
  }
}

export default new DataModel()

5.3. 列表项视图

// entry/src/main/ets/view/ToDoItem.ets
import CommonConstants from '../common/constant/CommonConstant'

@Component
export default struct ToDoItem {
  private content?: string
  @State isComplete: boolean = false

  @Builder labelIcon(icon: Resource) {
    Image(icon)
      .objectFit(ImageFit.Contain)
      .width($r('app.float.checkbox_width'))
      .height($r('app.float.checkbox_width'))
      .margin($r('app.float.checkbox_margin'))
  }

  build() {
    Row() {
      if (this.isComplete) {
        this.labelIcon($r('app.media.ic_ok'))
      } else {
        this.labelIcon($r('app.media.ic_default'))
      }

      Text(this.content)
        .fontSize($r('app.float.item_font_size'))
        .fontWeight(CommonConstants.FONT_WEIGHT)
        .opacity(this.isComplete 
                 ? CommonConstants.OPACITY_COMPLETED 
                 : CommonConstants.OPACITY_DEFAULT)
        .decoration({ type: this.isComplete 
          ? TextDecorationType.LineThrough : TextDecorationType.None })
    }
    .borderRadius(CommonConstants.BORDER_RADIUS)
    .backgroundColor($r('app.color.start_window_background'))
    .width(CommonConstants.LIST_DEFAULT_WIDTH)
    .height($r('app.float.list_item_height'))
    .onClick(() => {
      this.isComplete = !this.isComplete
    })
  }
}

6. 代码与视频教程

完整案例代码与视频教程请参见:

代码:Code-05-04.zip。

视频:《我的任务清单》。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值