ArkTS:声明式UI语法
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤博客园地址:为敢技术(https://www.cnblogs.com/strengthen/ )
➤GitHub地址:https://github.com/strengthen
➤原文地址:https://www.cnblogs.com/strengthen/p/18471722
➤如果链接不是为敢技术的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
声明式描述,举例:看到的界面是什么样子的,在代码中就进行什么样的描述,过程则交由框架去实现。
状态驱动视图更新,举例: 在ArkTS中,状态是驱动应用变化的数据,视图则是与状态相关联的UI内容,当状态改变时,框架会自动更新与状态相关联的视图,实现内容的动态更新。
状态驱动视图更新,代码实现:首先,这个操作是使用装饰器@State,使变量isComplete成为状态变量。并且在UI描述时使用这个状态变量,建立起状态数据与视图间的依赖关系。当用户点击的时候,在点击事件里面,改变isComplete的状态,ArkUI感知到了状态变化后,会直接触发视图的更新,这就是声明式的第二特征:状态驱动视图更新。
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; }) } }
@Entry装饰器的作用,表示这是一个入口页面,可以通过UIAbility进行加载,
声明了自定义组件后,还需要UI描述才能够展示内容。需要在struct结构体内,配置build函数,build函数是自定义组件进行声明式UI描述的地方。build函数采用花括号,包裹要描述的UI,UI描述中采用大括号和缩进,来区分组件,以及内部的内容。
在这个ToDoListPage自定义组件内,包含了有作为容器的Column,Column内部包含了用于显示文字的Text组件,以及封装的自定义组件ToDoItem。通过对页面内容进行合理抽象,提取结构相同以及功能明确的UI单元,组合为自定义组件,并且对自定义组件进行合理组合,就能够完成应用页面的搭建。
ToDoItem是一个圆圈和一个文字在横向排列,这里涉及到两个组件间的排列关系,就需要布局来组织这种多个组件之间的排列关系。
布局:多个组件的排列关系。
容器组件:描述多个组件间布局关系的组件。
使用方式是采用花括号语法,来包括想要组织的内容。相应的内容在其中按照顺序进行排列。
Row容器是一种行排列容器,在其中的组件会按照横向排列。
定义一个content的属性,来保存传入的内容,然后通过Text组件,展示content内容,在使用该组件时,对花括号中content传入相应的内容,就可以创建对应内容的ToDo Item组件。
Column是一种列布局容器,在其中的组件会按照纵向排列。
1、通过调整代办标题的样式,熟悉了如何对组件进行属性的配置。
2、自定义组件的封装。
3、使用容器描述布局。
通过ArkTS提供的装饰器@State,来装饰isComplete,从而让视图和状态之间建立绑定关系,
像这种控制页面内容消失和生成,可以使用if/else条件渲染语句。在if和else分支中,分别根据条件condition的不同,来展示不同的内容。
对于文字部分,为了更好的突出已完成状态,可以让文字更淡一些,并加一个删除线,来更好的让用户知道任务已完成。
使用opacity来控制不透明度。使用decoration属性,控制是否加删除线。
在Row容器上配置点击事件onClick,在事件内修改isComplete的值,就能够实现点击待办项,从而改变待办项显示的内容了。
列表可以有很多的列表项,如何完成多个列表项的构建?通过ForEach语法可以快速创建相应的UI内容。
ForEach需要接受的两个参数:
第一个参数是:数据源,
第二个参数是:生成器函数,函数的参数item,对应于数组的每一项内容,并在函数体内可以生成相应的页面布局content。
因为我们要实现的是对每一项数据,都生成一个待办项,所以要生成的内容,也就是ToDoItem自定义组件,
在ToDoListPage页面内,使用ForEach语法,就可以快速把数组内的数据渲染到页面上。
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')) } }