HarmonyOS鸿蒙Next中日历三方库cjcalendar日历下面添加不了东西
HarmonyOS鸿蒙Next中日历三方库cjcalendar日历下面添加不了东西 我使用https://ohpm.openharmony.cn/#/cn/detail/cjcalendar日历三方库想要在日历下面加上自己的List列表数据但是他却显示不出来,咋办
import {
CJCalendar,
CJCalendarControl,
CJCellStyle,
CJDateItem,
CJCalStatusParams,
OptMode,
SelectedStyle,
SelectedShape,
CJViewModel,
WeekStartMode,
CJDateShowBackMode
} from 'cjcalendar';
@Entry
@Component
struct CalendarDemo {
// 控制器,用于操作日历
controller: CJCalendarControl = new CJCalendarControl()
// 日历状态信息
@State calStatus: CJCalStatusParams = new CJCalStatusParams()
// 选中的日期
@State selectedDate: string = ''
// 自定义样式
@State cellStyle: CJCellStyle = new CJCellStyle()
@State isCalendarFold: boolean = false
@State listData: Array<string> = [
'item1', 'item2', 'item3', 'item4', 'item5',
'item6', 'item7', 'item8', 'item9', 'item10',
'item11', 'item12', 'item13', 'item14', 'item15',
'item16', 'item17', 'item18', 'item19', 'item20'
]
build() {
Column() {
// Stack() {
// // 标题居中显示
// Text(this.selectedDate ? `选中的日期: ${this.selectedDate}` : '未选择日期')
// .fontSize(16)
// .fontColor('#333')
// .margin({ top: 10, bottom: 10 })
// .width('100%')
// .textAlign(TextAlign.Center)
// // 右侧按钮组
// Row({ space: 12 }) {
// Text('今')
// .fontSize(14)
// .fontColor('#FFFFFF')
// .textAlign(TextAlign.Center)
// .width(32)
// .height(32)
// .backgroundColor('#ffffc51a')
// .borderRadius(16)
// .onClick(() => {
// // 跳转到今天
// const today = new Date();
// this.controller.skipToDate(today);
// console.warn('跳转到今天后的selectedDate:', this.selectedDate);
// })
// Image(this.isCalendarFold ? $r('app.media.ic_expand_more_24px') : $r('app.media.ic_expand_less_48px'))
// .width(24)
// .height(24)
// .onClick(() => {
// this.isCalendarFold = !this.isCalendarFold;
// this.controller.setFoldStatue(this.isCalendarFold);
// })
// }
// .height('100%')
// .justifyContent(FlexAlign.End)
// .margin({ right: 16 }) // 整个按钮组距离右边框16
// .width('100%')
// }
// .height(50)
// .backgroundColor(Color.Pink)
// .width('100%')
RelativeContainer() {
Text(this.selectedDate ? `选中的日期: ${this.selectedDate}` : '未选择日期')
.fontSize(16)
.fontColor('#333')
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
Row({ space: 12 }) {
Text('今')
.fontSize(14)
.fontColor('#FFFFFF')
.textAlign(TextAlign.Center)
.width(32)
.height(32)
.backgroundColor('#ffffc51a')
.borderRadius(16)
.onClick(() => {
// 跳转到今天
const today = new Date();
this.controller.skipToDate(today);
console.warn('跳转到今天后的selectedDate:', this.selectedDate);
})
Image(this.isCalendarFold ? $r('app.media.ic_expand_more_24px') : $r('app.media.ic_expand_less_48px'))
.width(24)
.height(24)
.onClick(() => {
this.isCalendarFold = !this.isCalendarFold;
this.controller.setFoldStatue(this.isCalendarFold);
})
}
.alignRules({
right: { anchor: '__container__', align: HorizontalAlign.End }
})
.margin({ right: 16 })
.alignItems(VerticalAlign.Center)
.height('100%')
}
.height(50)
.backgroundColor(Color.Pink)
.width('100%')
List() {
ForEach(
this.listData,
(item: string, index: number) => {
ListItem() {
Text(`${item}`)
.fontSize(18)
.fontColor('#333')
.backgroundColor('#FFFFFF')
.width('100%')
.padding(20)
.borderRadius(8)
}
},
(item: string) => item
)
}
.height(200)
.backgroundColor(Color.Pink)
// 日历
Column() {
CJCalendar({
// 控制器
controller: this.controller,
// 操作模式:单选
optMode: OptMode.SINGLE,
// 视图模式:月视图
viewModel: CJViewModel.MONTH,
// 从周一开始
weekStartMode: WeekStartMode.Monday,
// 显示农历
showLunar: false,
// 显示节日
showJieRi: false,
// 显示快捷返回今天按钮
showFastToday: false,
//显示工具栏
showToolbar: false,
// 标题栏高度
titleHeight: 60,
// 标题格式化
titleFormat: "yyyy年MM月",
// 主题色
themeColor: "#ffffc51a",
// 显示星期栏
showWeekTitle: true,
// 星期栏高度
weekTitleHeight: 40,
// 选中样式
selectedShape: SelectedShape.SHAPE_CIRCLE,
// 选中风格
selectedStyle: SelectedStyle.CLOSE,
// 是否显示折叠按钮'
isShowFoldView: false,
// 是否折叠
isFold: this.isCalendarFold,
// 日期选择回调
onSelectedChanged: (items: CJDateItem[]) => {
if (items.length > 0) {
const date = items[0];
this.selectedDate = `${date.fullYear}-${date.month + 1}-${date.date}`;
console.log('选择的日期:', this.selectedDate);
}
},
// 月份切换回调
onMonthChanged: (month: CJDateItem) => {
console.log('切换到月份:', month.month + 1);
},
// 日期点击事件
onCellItemClick: (item: CJDateItem) => {
console.log('点击日期:', item.date);
// 返回false表示不拦截默认操作
return false;
},
// 初始化完成回调
onInitFinish: () => {
console.log('日历初始化完成');
// 可以在这里进行数据初始化
},
// 自定义单元格样式
buildCellStyle: (item: CJDateItem) => {
const style = new CJCellStyle();
// 设置默认字体颜色
style.fontColor = '#333333';
style.markFontColor = '#666666';
// 周末特殊样式
// if (item.week === 0 || item.week === 6) {
// style.fontColor = '#1890ff';
// style.markFontColor = '#1890ff';
// }
// 今天特殊样式
if (item.isToday) {
style.todayFontColor = '#333333'; // 字体颜色与普通日期一致
style.todayBackgroundColor = '#00000000'; // 背景透明(或你想要的任何颜色)
style.borderColor = '#1890ff'; // 可选:加一个蓝色边框作为提示
style.borderWidth = 1;
style.borderRadius = 20; // 设置为圆形
}
// 选中样式
style.selectFontColor = '#ffffff';
style.selectItemBackgroundColor = '#ff9900';
// 禁用日期样式
style.disabledFontColor = '#cccccc';
// 标记样式
style.markFontSize = 10;
style.markFontColor = '#ff4d4f';
style.markSelectedFontColor = '#ff4d4f';
style.markBackgroundColor = '#fff2f0';
style.markRadius = 4;
return style;
},
// 重新构建单元格数据(添加自定义标记)
reBuildCellItem: (cjDateItem: CJDateItem) => {
// 为特定日期添加标记
const today = new Date();
const tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
// 明天添加标记
if (
cjDateItem.fullYear === tomorrow.getFullYear() &&
cjDateItem.month === tomorrow.getMonth() &&
cjDateItem.date === tomorrow.getDate()
) {
cjDateItem.markText = "明天";
}
// 节假日标记示例
// if (cjDateItem.fullYear === 2024 && cjDateItem.month === 9 && cjDateItem.date === 1) {
// cjDateItem.markText = "国庆";
// }
// 禁用过去的日期
// const itemDate = new Date(cjDateItem.fullYear, cjDateItem.month, cjDateItem.date);
// if (itemDate < today && !this.isSameDay(itemDate, today)) {
// cjDateItem.disabled = true;
// }
return cjDateItem;
},
// 自定义月份底部布局
buildMonthCustomLayout: this.CustomLayout,
// 是否将底部用户布局添加到整体,默认是每个月
isAttchCustomLayoutToWhole: false,
//仅显示日期区域
onlyShowDateArea: false
})
.width('100%')
.height('100%')
}
.width('100%')
}
.width('100%')
.height('100%')
}
@Builder
CustomLayout() {
Column() {
List() {
ForEach(
this.listData,
(item: string, index: number) => {
ListItem() {
Text(`${item}`)
.fontSize(18)
.fontColor('#333')
.backgroundColor('#FFFFFF')
.width('100%')
.padding(20)
.borderRadius(8)
}
},
(item: string) => item
)
}
.height(200)
.backgroundColor(Color.Pink)
Text('操作说明:点击日期可选中,选中日期背景为橙色。\n“明天”、“国庆”等为日期标记。')
.fontSize(14)
.fontColor('#1890ff')
.textAlign(TextAlign.Center)
.margin({
top: 20,
left: 20,
right: 20,
bottom: 10
})
.width('100%')
}
}
// 判断是否是同一天
isSameDay(date1: Date, date2: Date): boolean {
return date1.getFullYear() === date2.getFullYear() &&
date1.getMonth() === date2.getMonth() &&
date1.getDate() === date2.getDate();
}
}
更多关于HarmonyOS鸿蒙Next中日历三方库cjcalendar日历下面添加不了东西的实战教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,cjcalendar日历库添加不了内容,通常是因为该库未适配ArkTS/ArkUI,或API调用方式与鸿蒙Next不兼容。鸿蒙Next使用Stage模型和ArkTS,需确认cjcalendar是否支持该框架。检查库的版本是否针对HarmonyOS Next开发,并查看官方文档中关于日历组件数据绑定的示例。
更多关于HarmonyOS鸿蒙Next中日历三方库cjcalendar日历下面添加不了东西的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
根据你提供的代码,问题在于 buildMonthCustomLayout 中 @Builder 方法 CustomLayout 的作用域。
@Builder 方法默认无法直接访问组件内的状态变量(如 this.listData)。在你的代码中,CustomLayout 方法内部的 ForEach(this.listData, ...) 语句中的 this 指向的是 Builder 的上下文,而非你的 CalendarDemo 组件,因此 this.listData 是未定义的,导致列表无法渲染。
解决方案:
将 CustomLayout 方法修改为带参数的函数式 @Builder,并将 listData 作为参数传入。
-
修改
CustomLayout方法的定义和调用:// 1. 修改方法定义,添加参数 @Builder CustomLayout(listData: Array<string>) { Column() { List() { ForEach( listData, // 使用传入的参数 (item: string, index: number) => { ListItem() { Text(`${item}`) .fontSize(18) .fontColor('#333') .backgroundColor('#FFFFFF') .width('100%') .padding(20) .borderRadius(8) } }, (item: string) => item ) } .height(200) .backgroundColor(Color.Pink) Text('操作说明:点击日期可选中,选中日期背景为橙色。\n“明天”、“国庆”等为日期标记。') .fontSize(14) .fontColor('#1890ff') .textAlign(TextAlign.Center) .margin({ top: 20, left: 20, right: 20, bottom: 10 }) .width('100%') } } -
在
CJCalendar组件调用时传入listData:CJCalendar({ // ... 其他参数保持不变 buildMonthCustomLayout: () => { // 调用时传入当前组件的 listData this.CustomLayout(this.listData) }, // ... 其他参数保持不变 })
修改后,CustomLayout 将能正确接收到 listData 数据,并在日历底部渲染出你的列表。
核心原因: @Builder 装饰的方法有其独立的作用域。当它需要访问组件状态时,必须通过参数显式传递。直接使用 this 会指向错误的上下文对象,导致数据访问失败。

