简单的组件学习:
/*** weip 自定义控件* 自定义构建函数也是需要充电的地方,分全局和局部的* 全局:需要添加function关键字 局部:不加function关键字* @Styles function 自定义公共样式 分全局和局部* @Extends(Text) 继承模式 只能写成全局的* export:导出组件*/ @Component export struct Header {private title: ResourceStr;build() {// 标题部分Row() {// 资源自行替换,返回iconImage($r('app.media.app_icon')).width(30)Text(this.title).fontSize(30).fontWeight(FontWeight.Bold)Blank()// 资源自行替换,分享iconImage($r('app.media.app_icon')).width(30)}.width('100%').height(30)} }
ImagesPage.ets:
引用header组件
/*** 导入head组件*/ import { Header } from '../components/HeadComponents'// 全局自定义构建函数 function:代表全局 @Builder function ItemCard() {}// 组件内的局部函数需要加this // 自定义公共样式 @Styles function fillScreen() {.width('100%').height('100%').backgroundColor('#EFEFEF').padding(20) }// 自定义字体样式 需使用Extend() 继承模式,只能写在全局位置 @Extend(Text) function priceText() {.fontSize(18).fontColor('#F36') }@Entry @Component struct Index {@State imageWidth: number = 150// ForEach:循环遍历数组,根据数组内容渲染页面组件,超过屏幕的东西就看不到,也滑动不了,所以后面统一使用List组件build() {// 纵向布局 主轴/交叉轴,一般只设置主轴,不设置交叉轴Column() {// 标题Header({title: "图片详情"}).padding({left: 20, top: 20, right: 20, bottom: 20})// 横向布局 主轴/交叉轴,一般只设置主轴,不设置交叉轴Row(){Image($r('app.media.icon')).width(this.imageWidth).interpolation(ImageInterpolation.High)}.width('100%').height(400).justifyContent(FlexAlign.Center)// Row容器 放一行Row() {Text($r('app.string.width_label')).fontSize(20).fontWeight(FontWeight.Bold).fontColor('#663')TextInput({ placeholder: '请输入图片宽度', text:this.imageWidth.toFixed(0) }).width(150).backgroundColor('#FFF').type(InputType.Number).onChange(value => {console.log(value)this.imageWidth = parseInt(value)})}.width('100%').padding({left: 14,right: 14}).justifyContent(FlexAlign.SpaceBetween) // 中间留空// 分割线Divider().width('91%')// 两个按钮Row(){Button('缩小').width(80).fontSize(20).onClick(() => {if (this.imageWidth >= 10) {this.imageWidth -= 10;}})Button('放大').width(80).fontSize(20).onClick(() => {if (this.imageWidth < 300) {this.imageWidth += 10;}})}.width('100%').margin({top: 35, bottom: 35}).justifyContent(FlexAlign.SpaceEvenly)Slider({min: 100,max: 300,value: this.imageWidth,step: 10}).width('100%').blockColor('#36D').trackThickness(7).showTips(true).onChange(value => {// value:当前滑块值this.imageWidth = value;})}.width('100%').height('100%')} }/*** struct:自定义组件 可复用的UI单元* 装饰器:用来装饰类结构、方法、变量* @Component:标记自定义组件* @Entry:标记当前组件是入口组件* @State:标记一个变量是状态变量,值变化时会触发UI更新* build():UI描述,其内部以声明式方式描述UI结构* 内置组件:ArkUI提供的组件,比如容器组件如Row、Column* 基础组件:自带样式和功能的页面元素,如Text* 属性方法:设置组件的UI样式* 事件方法:设置组件的事件回调* 组件通用属性、特有属性(图片插值)*/
Index.ets:
一般是应用程序的入口
@Entry // 入口組件 @Component struct Index {@State message: string = 'Hello World'build() {Row() {Column() {Text(this.message).fontSize(50).fontWeight(FontWeight.Bold).fontColor('#36D').onClick(() => {this.message = 'Hello ArkTS!';})// Image('https://bkimg.cdn.bcebos.com/pic/bd315c6034a85edf8db139b7db031e23dd54564edf55?x-bce-process=image/format,f_auto/quality,Q_70/resize,m_lfit,limit_1,w_536')// .width('50%')// 引用本地图片资源地址Image($r('app.media.icon')).width(250).interpolation(ImageInterpolation.High)}.width('100%')}.height('100%')} }/*** struct:自定义组件 可复用的UI单元* 装饰器:用来装饰类结构、方法、变量* @Component:标记自定义组件* @Entry:标记当前组件是入口组件* @State:标记一个变量是状态变量,值变化时会触发UI更新* build():UI描述,其内部以声明式方式描述UI结构* 内置组件:ArkUI提供的组件,比如容器组件如Row、Column* 基础组件:自带样式和功能的页面元素,如Text* 属性方法:设置组件的UI样式* 事件方法:设置组件的事件回调* 组件通用属性、特有属性(图片插值)*/
PropPage.ets:
/*** 自定义任务类*/ class Task {// 静态变量,所有对象共享变量static id: number = 1// 任务名称 半角:``name: string = `任务${Task.id++}`// 任务状态:是否完成finished: boolean = false }// 统一的卡片样式 @Styles function card() {.width('95%').padding(20).backgroundColor(Color.White).borderRadius(15).shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4}) }// 任务完成样式 @Extend(Text) function finishedTask() {.decoration({type: TextDecorationType.LineThrough}).fontColor('#B1B2B1') }// 任务统计信息的实体类【c】 class StaticInfo {totalTask: number = 0;finishTask: number = 0; }@Entry @Component struct PropPage {// 总任务数量@State totalTask: number = 0// 已完成任务数量@State finishTask: number = 0build() {Column({space: 10}){// 任务进度卡片 子组件TaskStatistics({finishTask:this.finishTask, totalTask: this.totalTask})// 任务列表,包含新增任务 @Link totalTask:$finishTask:变量的引用TaskList({finishTask:$finishTask, totalTask: $totalTask})}.width('100%').height('100%').backgroundColor('#F1F2F3')} }@Component struct TaskList {// 总任务数量@Link totalTask: number// 已完成任务数量@Link finishTask: number// 任务数组@State tasks: Task[] = []handleTaskChange(){// 更新任务总数量this.totalTask = this.tasks.length// 更新已完成任务数量this.finishTask = this.tasks.filter(item => item.finished).length}build() {Column() {// 2、新增任务按钮Button('新增任务').width(200).onClick(() => {// 新增任务数据this.tasks.push(new Task())// 更新任务总数量this.handleTaskChange()})// 3、任务列表List({space: 10}) {ForEach(this.tasks,(item: Task, index) => {ListItem() {Row() {// 任务名Text(item.name).fontSize(20)// 任务复选框Checkbox().select(item.finished).onChange(isSelected => {// 任务状态发生变更,更新当前任务状态item.finished = isSelected// 更新已完成任务数量this.handleTaskChange()})}.card().justifyContent(FlexAlign.SpaceBetween)}.swipeAction({end: this.DeleteButton(index)})})}.width('100%').layoutWeight(1).alignListItem(ListItemAlign.Center)}}@Builder DeleteButton(index: number) {Button(){Image($r('app.media.icon')).fillColor(Color.White).width(20)}.width(40).height(40).type(ButtonType.Circle).backgroundColor(Color.Red).margin(5).onClick(() => {// 从角标开始删 删1个this.tasks.splice(index, 1)this.handleTaskChange()})} }/*** 任务进度卡片 子组件* 子组件是TaskStatistics 此时父组件是PropPage.ets* Prop:变量不能初始化 单向同步【父组件-->子组件】* Link:支持传对象 Prop:不支持传对象* provider 跨组件传输* consume 跨组件传输*/ @Component struct TaskStatistics {// 总任务数量@Prop totalTask: number// 已完成任务数量@Prop finishTask: numberbuild() {Row() {// 任务进度Text('任务进度').fontSize(30).fontWeight(FontWeight.Bold)// 堆叠容器Stack() {// 进度条Progress({value: this.finishTask,total: this.totalTask,type: ProgressType.Ring})// 1/5Row() {Text(this.finishTask.toString()).fontSize(24).fontColor('#36D')Text(' / ' + this.totalTask.toString()).fontSize(24)}}}.card().margin({top: 20, bottom: 20}).justifyContent(FlexAlign.SpaceEvenly)} }
预览效果图:
注解的学习:
/*** 自定义任务类*/ class Task {// 静态变量,所有对象共享变量static id: number = 1// 任务名称 半角:``name: string = `任务${Task.id++}`// 任务状态:是否完成finished: boolean = false }// 统一的卡片样式 @Styles function card() {.width('95%').padding(20).backgroundColor(Color.White).borderRadius(15).shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4}) }// 任务完成样式 @Extend(Text) function finishedTask() {.decoration({type: TextDecorationType.LineThrough}).fontColor('#B1B2B1') }// 任务统计信息的实体类 class StatInfo {totalTask: number = 0;finishTask: number = 0; }/*** 父组件*/ @Entry @Component struct PropPage {// 统计信息 【父亲】@State stat: StatInfo = new StatInfo()build() {Column({space: 10}){// 任务进度卡片 子组件TaskStatistics({finishTask:this.stat.finishTask, totalTask: this.stat.totalTask})// 任务列表,包含新增任务 @Link totalTask:$finishTask:变量的引用TaskList({stat:$stat})}.width('100%').height('100%').backgroundColor('#F1F2F3')} }@Component struct TaskList {// 统计信息【儿子】 Link可以传对象@Link stat: StatInfo// 任务数组@State tasks: Task[] = []handleTaskChange(){// 更新任务总数量this.stat.totalTask = this.tasks.length// 更新已完成任务数量this.stat.finishTask = this.tasks.filter(item => item.finished).length}build() {Column() {// 2、新增任务按钮Button('新增任务').width(200).onClick(() => {// 新增任务数据this.tasks.push(new Task())// 更新任务总数量this.handleTaskChange()})// 3、任务列表List({space: 10}) {ForEach(this.tasks,(item: Task, index) => {ListItem() {Row() {// 任务名Text(item.name).fontSize(20)// 任务复选框Checkbox().select(item.finished).onChange(isSelected => {// 任务状态发生变更,更新当前任务状态item.finished = isSelected// 更新已完成任务数量this.handleTaskChange()})}.card().justifyContent(FlexAlign.SpaceBetween)}.swipeAction({end: this.DeleteButton(index)})})}.width('100%').layoutWeight(1).alignListItem(ListItemAlign.Center)}}@Builder DeleteButton(index: number) {Button(){Image($r('app.media.icon')).fillColor(Color.White).width(20)}.width(40).height(40).type(ButtonType.Circle).backgroundColor(Color.Red).margin(5).onClick(() => {// 从角标开始删 删1个this.tasks.splice(index, 1)this.handleTaskChange()})} }/*** 任务进度卡片 子组件* 子组件是TaskStatistics 此时父组件是PropPage.ets* Prop:变量不能初始化 单向同步【父组件-->子组件】* Link:支持传对象 Prop:不支持传对象* provider 跨组件传输* consume 跨组件传输*/ @Component struct TaskStatistics {// 总任务数量@Prop totalTask: number// 已完成任务数量@Prop finishTask: numberbuild() {Row() {// 任务进度Text('任务进度').fontSize(30).fontWeight(FontWeight.Bold)// 堆叠容器Stack() {// 进度条Progress({value: this.finishTask,total: this.totalTask,type: ProgressType.Ring})// 1/5Row() {Text(this.finishTask.toString()).fontSize(24).fontColor('#36D')Text(' / ' + this.totalTask.toString()).fontSize(24)}}}.card().margin({top: 20, bottom: 20}).justifyContent(FlexAlign.SpaceEvenly)} }
跨组件传输数据:
@Provider @Consume
这种相对比较费内存,非跨组件不建议使用
/*** 自定义任务类*/ class Task {// 静态变量,所有对象共享变量static id: number = 1// 任务名称 半角:``name: string = `任务${Task.id++}`// 任务状态:是否完成finished: boolean = false }// 统一的卡片样式 @Styles function card() {.width('95%').padding(20).backgroundColor(Color.White).borderRadius(15).shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4}) }// 任务完成样式 @Extend(Text) function finishedTask() {.decoration({type: TextDecorationType.LineThrough}).fontColor('#B1B2B1') }// 任务统计信息的实体类 class StatInfo {totalTask: number = 0;finishTask: number = 0; }/*** 父组件*/ @Entry @Component struct PropPage {// 统计信息 【父亲】@Provide stat: StatInfo = new StatInfo()build() {Column({space: 10}){// 任务进度卡片 子组件TaskStatistics()// 任务列表,包含新增任务 @Link totalTask:$finishTask:变量的引用TaskList()}.width('100%').height('100%').backgroundColor('#F1F2F3')} }@Component struct TaskList {// 统计信息【儿子】 Link可以传对象@Consume stat: StatInfo// 任务数组@State tasks: Task[] = []handleTaskChange(){// 更新任务总数量this.stat.totalTask = this.tasks.length// 更新已完成任务数量this.stat.finishTask = this.tasks.filter(item => item.finished).length}build() {Column() {// 2、新增任务按钮Button('新增任务').width(200).onClick(() => {// 新增任务数据this.tasks.push(new Task())// 更新任务总数量this.handleTaskChange()})// 3、任务列表List({space: 10}) {ForEach(this.tasks,(item: Task, index) => {ListItem() {Row() {// 任务名Text(item.name).fontSize(20)// 任务复选框Checkbox().select(item.finished).onChange(isSelected => {// 任务状态发生变更,更新当前任务状态item.finished = isSelected// 更新已完成任务数量this.handleTaskChange()})}.card().justifyContent(FlexAlign.SpaceBetween)}.swipeAction({end: this.DeleteButton(index)})})}.width('100%').layoutWeight(1).alignListItem(ListItemAlign.Center)}}@Builder DeleteButton(index: number) {Button(){Image($r('app.media.icon')).fillColor(Color.White).width(20)}.width(40).height(40).type(ButtonType.Circle).backgroundColor(Color.Red).margin(5).onClick(() => {// 从角标开始删 删1个this.tasks.splice(index, 1)this.handleTaskChange()})} }/*** 任务进度卡片 子组件* 子组件是TaskStatistics 此时父组件是PropPage.ets* Prop:变量不能初始化 单向同步【父组件-->子组件】* Link:支持传对象 Prop:不支持传对象* provider 跨组件传输* consume 跨组件传输*/ @Component struct TaskStatistics {// 统计信息@Consume stat: StatInfobuild() {Row() {// 任务进度Text('任务进度').fontSize(30).fontWeight(FontWeight.Bold)// 堆叠容器Stack() {// 进度条Progress({value: this.stat.finishTask,total: this.stat.totalTask,type: ProgressType.Ring})// 1/5Row() {Text(this.stat.finishTask.toString()).fontSize(24).fontColor('#36D')Text(' / ' + this.stat.totalTask.toString()).fontSize(24)}}}.card().margin({top: 20, bottom: 20}).justifyContent(FlexAlign.SpaceEvenly)} }
// bind(this)
/*** 自定义任务类*/ @Observed class Task {// 静态变量,所有对象共享变量static id: number = 1// 任务名称 半角:``name: string = `任务${Task.id++}`// 任务状态:是否完成finished: boolean = false }// 统一的卡片样式 @Styles function card() {.width('95%').padding(20).backgroundColor(Color.White).borderRadius(15).shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4}) }// 任务完成样式 @Extend(Text) function finishedTask() {.decoration({type: TextDecorationType.LineThrough}).fontColor('#B1B2B1') }// 任务统计信息的实体类 class StatInfo {totalTask: number = 0;finishTask: number = 0; }/*** 父组件*/ @Entry @Component struct PropPage {// 统计信息 【父亲】@Provide stat: StatInfo = new StatInfo()build() {Column({space: 10}){// 任务进度卡片 子组件TaskStatistics()// 任务列表,包含新增任务 @Link totalTask:$finishTask:变量的引用TaskList()}.width('100%').height('100%').backgroundColor('#F1F2F3')} }@Component struct TaskList {// 统计信息【儿子】 Link可以传对象@Consume stat: StatInfo// 任务数组@State tasks: Task[] = []handleTaskChange(){// 更新任务总数量this.stat.totalTask = this.tasks.length// 更新已完成任务数量this.stat.finishTask = this.tasks.filter(item => item.finished).length}build() {Column() {// 2、新增任务按钮Button('新增任务').width(200).onClick(() => {// 新增任务数据this.tasks.push(new Task())// 更新任务总数量this.handleTaskChange()})// 3、任务列表List({space: 10}) {ForEach(this.tasks,(item: Task, index) => {ListItem() {// bind(this) 绑定父组件的thisTaskItem({item: item, onTaskChange: this.handleTaskChange.bind(this)})}.swipeAction({end: this.DeleteButton(index)})})}.width('100%').layoutWeight(1).alignListItem(ListItemAlign.Center)}}@Builder DeleteButton(index: number) {Button(){Image($r('app.media.icon')).fillColor(Color.White).width(20)}.width(40).height(40).type(ButtonType.Circle).backgroundColor(Color.Red).margin(5).onClick(() => {// 从角标开始删 删1个this.tasks.splice(index, 1)this.handleTaskChange()})} }/*** 自定义任务的item项* 方法传递*/ @Component struct TaskItem {@ObjectLink item: Task// 变量的类型是个函数类型onTaskChange: () => voidbuild() {Row() {// 任务名 如果完成,需要变灰if (this.item.finished) {Text(this.item.name).fontSize(20).finishedTask()} else {Text(this.item.name).fontSize(20)}// 任务复选框Checkbox().select(this.item.finished).onChange(isSelected => {// 任务状态发生变更,更新当前任务状态this.item.finished = isSelected// 更新已完成任务数量//this.handleTaskChange()this.onTaskChange()})}.card().justifyContent(FlexAlign.SpaceBetween)} }/*** 任务进度卡片 子组件* 子组件是TaskStatistics 此时父组件是PropPage.ets* Prop:变量不能初始化 单向同步【父组件-->子组件】* Link:支持传对象 Prop:不支持传对象* provider 跨组件传输* consume 跨组件传输*/ @Component struct TaskStatistics {// 统计信息@Consume stat: StatInfobuild() {Row() {// 任务进度Text('任务进度').fontSize(30).fontWeight(FontWeight.Bold)// 堆叠容器Stack() {// 进度条Progress({value: this.stat.finishTask,total: this.stat.totalTask,type: ProgressType.Ring})// 1/5Row() {Text(this.stat.finishTask.toString()).fontSize(24).fontColor('#36D')Text(' / ' + this.stat.totalTask.toString()).fontSize(24)}}}.card().margin({top: 20, bottom: 20}).justifyContent(FlexAlign.SpaceEvenly)} }