简介
实现某一天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)
}
}
总结
现在仅简单的实现层叠效果,后续优化点:
- 实现事件卡片边框可以上下拖动修改事件卡片的高度。
- 实现事件卡片可以拖动效果,修改事件卡片的位置。
- 实现点击时,临时添加一个事件卡片,方便用户编辑标题和起始结束时间。
- 需要解决时间重叠时的显示问题。