简介
实现某一天24小时的时间长度和当天事件的页面。实现如下的效果:
代码
代码架构
- List_Page:主界面
- NumberUtil:数字辅助类
- DateEvenModel:日程实体类
- ListPageViewModel:界面交互类
List_Page
import { DateEvenModel } from '../Models/DateEvenModel'; import { ListPageViewModel } from '../ViewModels/ListPageViewModel'; @Entry @Component struct List_Page { @State VM: ListPageViewModel = new ListPageViewModel(); aboutToAppear(): void { this.VM.TimeListInit(); this.VM.DateModelInit(); } @Builder DateEventCard(model: DateEvenModel) { Row() { Column() .backgroundColor("#adc9f9") .width(4) .height("100%") .borderRadius({ topLeft: 5, bottomLeft: 5 }) Column() { Text(model.Title) .fontSize(10) .fontColor(model.FontColor) .margin({ top: 3, left: 3 }) } .borderRadius(0) } .alignItems(VerticalAlign.Top) .borderRadius(5) .backgroundColor(model.BackgroundColor) .width("100%") .height(model.Height) .translate({ x: model.OffsetX, y: model.OffsetY, z: 0 }) } build() { Stack({ alignContent: Alignment.TopStart }) { //时间线主体 Scroll(this.VM.TimeScroller) { Column() { ForEach(this.VM.TimeList, (item: string, index: number) => { Row() { Text(item) .width(50) Column() { Divider().width("100%").backgroundColor("#e2e2e2").margin({ top: 8 }).strokeWidth(1) } .margin({ right: 10 }) .layoutWeight(1) .height("100%") } .alignItems(VerticalAlign.Top) .justifyContent(FlexAlign.Start) .width("100%") .height(60) .width("100%") }) } .height(1440) } .width("100%") .scrollBar(BarState.Off) //事件列表 Scroll(this.VM.DateScroller) { Stack({ alignContent: Alignment.TopStart }) { ForEach(this.VM.DateEventList, (item: DateEvenModel, index) => { this.DateEventCard(item) }) } .width("100%") .height(1440) } .padding({ left: 50, right: 10 }) .width("100%") .onDidScroll((xOffset: number, yOffset: number, scrollState: ScrollState) => { console.info("我是List" + yOffset.toString()); console.info("我是状态:" + scrollState.toString()); if (scrollState == ScrollState.Scroll) { this.VM.TimeScroller.scrollTo({ xOffset: 0, yOffset: this.VM.TimeScroller.currentOffset().yOffset + yOffset }) } }) } .height('100%') .width('100%') } }
NumberUtil
export class NumberUtil { /** * 格式化数字,用0补位 * @param num 数字 * @param length 数字长度 * @returns */ static PrefixInteger(num: number, length: number) { return (Array(length).join('0') + num).slice(-length); } }
DateEvenModel
@Observed /** * 单天日程 */ export class DateEvenModel { /** * X轴偏移值 */ OffsetX: number = 0; /** * Y轴偏移值 */ OffsetY: number = 0; /** * 左上角X轴坐标值 */ PositionX: number = 0; /** * 左上角Y轴偏移值 */ PositionY: number = 0; /** * 卡片高度 */ Height: number = 15; /** * 卡片背景颜色 */ BackgroundColor: ResourceColor = Color.Black; /** * 卡片字体颜色 */ FontColor: ResourceColor = Color.White; StartTime: Date = new Date(); EndTime: Date = new Date(); Title: string = ""; constructor() { } }
ListPageViewModel
import { DateEvenModel } from '../Models/DateEvenModel'; import { NumberUtil } from '../Utils/NumberUtil'; @Observed /** * 界面交互类 */ export class ListPageViewModel { TimeList: Array<string> = []; DateEventList: Array<DateEvenModel> = new Array<DateEvenModel>(); TimeScroller: Scroller = new Scroller(); DateScroller: Scroller = new Scroller(); constructor() { } /** * 时间列表集合初始化 */ public TimeListInit(): void { for (let index = 0; index < 24; index++) { this.TimeList.push(`${NumberUtil.PrefixInteger(index, 2)}:00`) } } public DateModelInit(): void { let model1: DateEvenModel = new DateEvenModel(); model1.PositionY = model1.OffsetY = 360; model1.Title = "测试1"; model1.Height = 120; model1.BackgroundColor = "#e9fae8"; model1.FontColor = "#97af96"; let model2: DateEvenModel = new DateEvenModel(); model2.PositionY = model2.OffsetY = model1.Height + model1.OffsetY; model2.Title = "测试2"; model2.Height = 30; model2.BackgroundColor = "#2b2b2b"; model2.FontColor = "#64c8c2"; let model3: DateEvenModel = new DateEvenModel(); model3.PositionY = model3.OffsetY = model2.Height + model2.OffsetY + 30; model3.Title = "测试3"; this.DateEventList.push(model1, model2, model3) } }
总结
现在仅简单的实现层叠效果,后续优化点:
- 实现事件卡片边框可以上下拖动修改事件卡片的高度。
- 实现事件卡片可以拖动效果,修改事件卡片的位置。
- 实现点击时,临时添加一个事件卡片,方便用户编辑标题和起始结束时间。
- 需要解决时间重叠时的显示问题。