# ArkTS 水果排行榜 > 代码可执行 > 分为五个文件 > 1.FruitDataModel.ets 定义app中需要的水果模型 > 2.TitleComponent.ets 定义Title组件 > 3.TableHeaderComponent.ets 定义表头组件 > 4.ItemComponent.ets 定义列表项的子组件 >5.Index.ets UI入口组件
FruitDataModel.ets文件 定义app中需要的水果模型
/** * Models 水果对象 */ export class FruitDataModel { private name:string private vote:string private id:string constructor(id:string, name:string, vote:string) { this.id = id this.name = name this.vote = vote } }
TitleComponent.ets文件 定义Title组件
/** * TitleComponent Title组件 */ import AppContext from '@ohos.app.ability.common' @Component export struct TitleComponent { @Link isRefreshData: boolean // 定义一个共享变量,是否刷新数据 @State title: string = '水果排行榜' // 定义一个标题状态变量 build() { Row() { // 分为两部分 // 第一部分:又由两部分组成。1、返回图标。2、标题 Row() { Image($r('app.media.ic_back')) // 返回按钮图片 .height(21) .width(21) .margin({right: 18}) .onClick(()=>{ // 退出整个APP let context = getContext(this) as AppContext.UIAbilityContext // 获得上下文对象 context.terminateSelf() // 关闭当前组件(退出) }) Text(this.title) .fontSize('30.00fp') } .width('50%') .height('100%') .justifyContent(FlexAlign.Start) // 第二部分 Row() { Image($r('app.media.ic_loading')) // 刷新按钮图标 .width(22) .height(22) .onClick(()=>{ this.isRefreshData = !this.isRefreshData }) } .width('50%') .height('100%') .justifyContent(FlexAlign.End) } .width('100%') .height(47) .padding({left:26, right: 26}) .margin({top:10}) .justifyContent(FlexAlign.SpaceAround) // 平均分布 } }
TableHeaderComponent.ets 定义表头组件
/** * 表头组件 */ @Component export struct TableHeaderComponent { paddingValue: Padding|Length = 0 widthValue: Length = 0 // 表头组件所占用的宽度 build() { Row() { Text('排名') .fontSize(16) .width('20%') .fontWeight(400) .fontColor('#989A9C') Text('种类') .fontSize(16) .width('50%') .fontWeight(400) .fontColor('#989A9C') Text('得票数') .fontSize(16) .width('30%') .fontWeight(400) .fontColor('#989A9C') } .width(this.widthValue) .padding(this.paddingValue) } }
ItemComponent.ets 定义列表项的子组件
/** * 列表项的子组件 */ @Component export struct ItemComponent { private index: number private name: string private vote: string @State isChoice: boolean = false // 该行数据是否选中 build() { Row() { // 三部分组成 // 第一部分: 排名 Column() { if (this.isCircleText()) { // 圆形的文本框 this.CreateCircle(this.index) } else { Text(this.index.toString()) .lineHeight(24) .textAlign(TextAlign.Center) .fontSize(16) .fontWeight(400) .width(24) } } .width('20%') .alignItems(HorizontalAlign.Start) // 第二部分:种类 Text(this.name) .width('50%') .fontWeight(500) .fontSize(18) .fontColor(this.isChoice ? Color.Blue : '#182431') // 第三部分:得票数 Text(this.vote) .width('30%') .fontSize(16) .fontWeight(400) .fontColor(this.isChoice ? Color.Blue : '#182431') } .width('100%') .height(48) .onClick(()=>{ // 选中该行之后,颜色要变化 this.isChoice = !this.isChoice }) } @Builder // 构建函数 CreateCircle(index: number) { Row() { Text(this.index.toString()) .fontWeight(40) .fontSize(16) .fontColor(Color.White) } .justifyContent(FlexAlign.Center) .borderRadius(24) .size({width:24, height: 24}) .backgroundColor(Color.Blue) } isCircleText(): boolean { // 判断排名 是否为前3名 return this.index === 1|| this.index === 2 || this.index === 3 } }
Index.ets UI入口组件
/** * 入口UI */ import {FruitDataModel} from './FruitDataModel' import {ItemComponent} from './ItemComponent' import {TableHeaderComponent} from './TableHeaderComponent' import {TitleComponent} from './TitleComponent' @Entry @Component struct Index { @State dataSource1: FruitDataModel[] = [ new FruitDataModel('1', '苹果', '12000'), new FruitDataModel('2', '葡萄', '10320'), new FruitDataModel('3', '西瓜', '9801'), new FruitDataModel('4', '香蕉', '8431'), new FruitDataModel('5', '菠萝', '7546'), new FruitDataModel('6', '榴莲', '7431'), new FruitDataModel('7', '红葡萄', '7187'), new FruitDataModel('8', '梨子', '7003'), new FruitDataModel('9', '杨桃', '6794'), new FruitDataModel('10', '番石榴', '6721') ] @State dataSource2: FruitDataModel[] = [ new FruitDataModel('11', '西瓜', '8836'), new FruitDataModel('12', '苹果', '8521'), new FruitDataModel('13', '香蕉', '8431'), new FruitDataModel('14', '葡萄', '7909'), new FruitDataModel('15', '红葡萄', '7547'), new FruitDataModel('16', '梨子', '7433'), new FruitDataModel('17', '菠萝', '7186'), new FruitDataModel('18', '榴莲', '7023'), new FruitDataModel('19', '番石榴', '6794'), new FruitDataModel('20', '杨桃', '6721') ] @State isSwitchDataSource: boolean = true // 是否切换数据源 build() { Column() { // 分为三部分 // 第一部分:标题组件 TitleComponent({isRefreshData:$isSwitchDataSource, title: '水果排行榜'}) // Link组件必须家$符号 // 第二部分:表头组件 TableHeaderComponent({ paddingValue: { left: 15, right: 15 }, widthValue: '92%' }) .margin({ top: 20, bottom: 15 }) // 第三部分:列表 this.CreateArrayItemComponent() } .backgroundColor('#F1F3F5') .width('100%') .height('100%') } @Builder CreateArrayItemComponent(){ // 构建一个列表 Column() { List() { ForEach(this.isSwitchDataSource ? this.dataSource1 : this.dataSource2, // 根据状态的值来切换不同的数据源 (item:FruitDataModel, index: number) => { // 构建列表项 ListItem() { ItemComponent({ index: index + 1, // @ts-ignore name: item.name, // @ts-ignore vote: item.vote }) } }) } .width('100%') .height('65%') .divider({strokeWidth: 1}) } .padding({ left: 15, right: 15 }) .width('92%') .borderRadius(20) .alignItems(HorizontalAlign.Center) .backgroundColor(Color.White) } }
效果展示
来源B站公开视频: