0.0.8:卡片整卡可点 —— 点空白处也能进 App 并定位到当天
用户反馈:卡片的空白区域点了没反应,只有落在日程/文字上才跳转。
期望:点卡片**任何位置**都进入 App 并**定位到卡片当前显示的那一天**。
实现(4 张卡片:2x2 / 2x4 / 4x4 / 6x4 一致处理):
1. 根容器加 `.onClick(() => this.openApp())` → **整卡可点**(含留白);
2. `openApp()` 携带 `openDate` 深链参数,值为卡片数据里的 `selectedDate`
(该字段早已在 CardData 中维护:CardDataService.ets:194 = 卡片当前显示日 0 点毫秒);
3. **传参必须转字符串**:`params: { openDate: `${this.selectedDate}` }`。
⚠️ 依据 4x4 原有注释:param 的数值按 **int32** 传递,13 位毫秒时间戳会溢出成
2147483647(曾导致进 App 后定位到 1970)。2x2/4x2 原本传的是 number → 已修正为字符串。
4. **移除内部原有的 openApp 点击**(共 13 处:4x2 四、4x4 四、6x4 五),
避免"子区域 + 根容器"双重触发同一动作。
关于事件冒泡(重要,避免误改):
- ArkUI 的 `onClick` 是**非冒泡**事件,父子组件同绑时**子组件优先**,同一时刻只有一个响应
(华为官方论坛结论)。因此:
· 根容器整卡可点**不会**抢走内部 ‹ › 今 + 按钮的点击;
· **无需** `stopPropagation`(ClickEvent 上也**没有**这个方法——它只在
MouseEvent / TouchEvent 上,实测编译报错已验证)。
- 内部原有的 4x4/6x4 注释写"兄弟节点布局不冒泡"是对的;本次统一补上说明。
验证:
- 编译通过(BUILD SUCCESSFUL)。
- 四卡一致性核验:每卡 openApp 点击点=1(仅根容器)、根容器=1、selectedDate 声明=1、
openDate 字符串传参=1。
- 结构完整性:花括号配平(26/26、53/53、228/228、228/228),编译无语法错误。
⚠️ 未验证(待真机):实际点击留白是否跳转、是否正确定位到所显示的那一天;
以及点 ‹ › 今 + 是否**不会**连带打开 App(依赖上述"子组件优先"结论,需实测确认)。
This commit is contained in:
@@ -11,8 +11,12 @@ struct Widget2x2Card {
|
|||||||
@LocalStorageProp('dateMd') dateMd: string = '';
|
@LocalStorageProp('dateMd') dateMd: string = '';
|
||||||
@LocalStorageProp('weekday') weekday: string = '';
|
@LocalStorageProp('weekday') weekday: string = '';
|
||||||
@LocalStorageProp('todayCount') todayCount: number = 0;
|
@LocalStorageProp('todayCount') todayCount: number = 0;
|
||||||
|
/** 卡片当前显示的那一天 0 点毫秒 —— 点卡片进 App 时定位到这一天 */
|
||||||
|
@LocalStorageProp('selectedDate') selectedDate: number = 0;
|
||||||
|
|
||||||
/** 右上角添加按钮:拉起 App 直接进入新建日程页(阻止冒泡,避免同时打开 App 首页) */
|
/** 右上角添加按钮:拉起 App 直接进入新建日程页。
|
||||||
|
* ⭐ 无需阻止冒泡:ArkUI 的 `onClick` 是**非冒泡**事件,父子同绑时**子组件优先**,
|
||||||
|
* 故点 + 不会连带触发根容器的"打开首页"。 */
|
||||||
@Builder
|
@Builder
|
||||||
addButton() {
|
addButton() {
|
||||||
Button() {
|
Button() {
|
||||||
@@ -35,12 +39,12 @@ struct Widget2x2Card {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 卡片"打开 App":点击日期区或今日日程数区域触发;添加按钮是 header 行的兄弟节点,其点击不会冒泡到这里 */
|
/** 打开 App 并**定位到卡片当前显示的那一天**(用户可能已翻到其他日期) */
|
||||||
private openApp(): void {
|
private openApp(): void {
|
||||||
postCardAction(this, {
|
postCardAction(this, {
|
||||||
action: 'router',
|
action: 'router',
|
||||||
abilityName: 'EntryAbility',
|
abilityName: 'EntryAbility',
|
||||||
params: {}
|
params: { openDate: `${this.selectedDate}` }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +65,6 @@ struct Widget2x2Card {
|
|||||||
}
|
}
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.alignItems(HorizontalAlign.Start)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
|
|
||||||
this.addButton()
|
this.addButton()
|
||||||
}
|
}
|
||||||
@@ -92,12 +95,13 @@ struct Widget2x2Card {
|
|||||||
.width('100%')
|
.width('100%')
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.alignItems(VerticalAlign.Center)
|
.alignItems(VerticalAlign.Center)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.padding(14)
|
.padding(14)
|
||||||
.backgroundColor('#FFFFFF')
|
.backgroundColor('#FFFFFF')
|
||||||
.borderRadius(16)
|
.borderRadius(16)
|
||||||
|
// ⭐ 整卡可点:空白处也能进 App 并定位到当前显示日(原来只有日期区/条数区可点)
|
||||||
|
.onClick(() => this.openApp())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ struct Widget4x2Card {
|
|||||||
@LocalStorageProp('lunarText') lunarText: string = '';
|
@LocalStorageProp('lunarText') lunarText: string = '';
|
||||||
@LocalStorageProp('todayCount') todayCount: number = 0;
|
@LocalStorageProp('todayCount') todayCount: number = 0;
|
||||||
@LocalStorageProp('ongoingJson') ongoingJson: string = '[]';
|
@LocalStorageProp('ongoingJson') ongoingJson: string = '[]';
|
||||||
|
/** 卡片当前显示的那一天 0 点毫秒 —— 点卡片进 App 时定位到这一天 */
|
||||||
|
@LocalStorageProp('selectedDate') selectedDate: number = 0;
|
||||||
|
|
||||||
/** 右侧最多渲染 2 条(数据侧已裁剪,这里再兜底截断) */
|
/** 右侧最多渲染 2 条(数据侧已裁剪,这里再兜底截断) */
|
||||||
private parseOngoing(): CardItem2x4[] {
|
private parseOngoing(): CardItem2x4[] {
|
||||||
@@ -57,12 +59,12 @@ struct Widget4x2Card {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 卡片"打开 App":点击左侧日期区、今日条数区、右侧日程区触发;添加按钮是 header 行兄弟节点,不冒泡 */
|
/** 打开 App 并**定位到卡片当前显示的那一天**(用户可能已翻到其他日期) */
|
||||||
private openApp(): void {
|
private openApp(): void {
|
||||||
postCardAction(this, {
|
postCardAction(this, {
|
||||||
action: 'router',
|
action: 'router',
|
||||||
abilityName: 'EntryAbility',
|
abilityName: 'EntryAbility',
|
||||||
params: {}
|
params: { openDate: `${this.selectedDate}` }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +120,6 @@ struct Widget4x2Card {
|
|||||||
.width('100%')
|
.width('100%')
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.justifyContent(FlexAlign.Center)
|
.justifyContent(FlexAlign.Center)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
@@ -141,7 +142,6 @@ struct Widget4x2Card {
|
|||||||
}
|
}
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.alignItems(HorizontalAlign.Start)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
|
|
||||||
this.addButton()
|
this.addButton()
|
||||||
}
|
}
|
||||||
@@ -173,7 +173,6 @@ struct Widget4x2Card {
|
|||||||
.width('100%')
|
.width('100%')
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.alignItems(VerticalAlign.Center)
|
.alignItems(VerticalAlign.Center)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.height('100%')
|
.height('100%')
|
||||||
@@ -197,7 +196,6 @@ struct Widget4x2Card {
|
|||||||
.width('100%')
|
.width('100%')
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.justifyContent(FlexAlign.Center)
|
.justifyContent(FlexAlign.Center)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
@@ -208,5 +206,7 @@ struct Widget4x2Card {
|
|||||||
.padding(12)
|
.padding(12)
|
||||||
.backgroundColor('#FFFFFF')
|
.backgroundColor('#FFFFFF')
|
||||||
.borderRadius(16)
|
.borderRadius(16)
|
||||||
|
// ⭐ 整卡可点:左右空白处也能进 App 并定位到当前显示日
|
||||||
|
.onClick(() => this.openApp())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -387,7 +387,9 @@ struct Widget4x4Card {
|
|||||||
return h < 10 ? `0${h}` : `${h}`;
|
return h < 10 ? `0${h}` : `${h}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 右上角添加按钮:拉起 App 直接进入新建日程页(兄弟节点布局,不冒泡到其它点击区) */
|
/** 右上角添加按钮:拉起 App 直接进入新建日程页。
|
||||||
|
* ⭐ 无需阻止冒泡:ArkUI 的 `onClick` 是**非冒泡**事件,父子同绑时**子组件优先**,
|
||||||
|
* 故点 + 不会连带触发根容器的"打开首页"。 */
|
||||||
@Builder
|
@Builder
|
||||||
addButton() {
|
addButton() {
|
||||||
Button() {
|
Button() {
|
||||||
@@ -442,6 +444,7 @@ struct Widget4x4Card {
|
|||||||
.borderRadius(11)
|
.borderRadius(11)
|
||||||
.padding(0)
|
.padding(0)
|
||||||
.backgroundColor('#F2F3F5')
|
.backgroundColor('#F2F3F5')
|
||||||
|
// ⭐ 无需阻止冒泡:onClick 非冒泡、子组件优先 → 点翻页不会连带打开 App
|
||||||
.onClick(() => this.page(act))
|
.onClick(() => this.page(act))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,6 +465,7 @@ struct Widget4x4Card {
|
|||||||
.borderRadius(11)
|
.borderRadius(11)
|
||||||
.padding(0)
|
.padding(0)
|
||||||
.backgroundColor('#007DFF')
|
.backgroundColor('#007DFF')
|
||||||
|
// ⭐ 无需阻止冒泡:onClick 非冒泡、子组件优先
|
||||||
.onClick(() => this.page('today'))
|
.onClick(() => this.page('today'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -554,7 +558,6 @@ struct Widget4x4Card {
|
|||||||
.width('100%')
|
.width('100%')
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.justifyContent(FlexAlign.Center)
|
.justifyContent(FlexAlign.Center)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
} else {
|
} else {
|
||||||
List({ space: 4 }) {
|
List({ space: 4 }) {
|
||||||
ForEach(this.parseList(), (item: LItem4) => {
|
ForEach(this.parseList(), (item: LItem4) => {
|
||||||
@@ -568,7 +571,6 @@ struct Widget4x4Card {
|
|||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.scrollBar(BarState.Auto)
|
.scrollBar(BarState.Auto)
|
||||||
.cachedCount(8)
|
.cachedCount(8)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,7 +591,6 @@ struct Widget4x4Card {
|
|||||||
}
|
}
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.alignItems(HorizontalAlign.Start)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
this.pageBtn('›', 'next')
|
this.pageBtn('›', 'next')
|
||||||
this.sideBtn()
|
this.sideBtn()
|
||||||
}
|
}
|
||||||
@@ -630,7 +631,6 @@ struct Widget4x4Card {
|
|||||||
.padding({ left: 5, right: 5 })
|
.padding({ left: 5, right: 5 })
|
||||||
.borderRadius(5)
|
.borderRadius(5)
|
||||||
.backgroundColor(a.color)
|
.backgroundColor(a.color)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
}, (a: TAllDay, idx: number) => `ad_${idx}_${a.eventKey}`)
|
}, (a: TAllDay, idx: number) => `ad_${idx}_${a.eventKey}`)
|
||||||
if (this.w4AllDayRest() > 0) {
|
if (this.w4AllDayRest() > 0) {
|
||||||
Text(`还有 ${this.w4AllDayRest()} 个全天日程`)
|
Text(`还有 ${this.w4AllDayRest()} 个全天日程`)
|
||||||
@@ -690,6 +690,9 @@ struct Widget4x4Card {
|
|||||||
.padding(12)
|
.padding(12)
|
||||||
.backgroundColor('#FFFFFF')
|
.backgroundColor('#FFFFFF')
|
||||||
.borderRadius(16)
|
.borderRadius(16)
|
||||||
|
// ⭐ 整卡可点:空白处也能进 App 并定位到当前显示日。
|
||||||
|
// ⚠️ onClick 是**非冒泡**事件且**子组件优先** → 内部的 ‹ › 今 + 按钮不会被这里抢走
|
||||||
|
.onClick(() => this.openApp())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 第 1 层:整点网格(每小时一格,格底一条灰线) */
|
/** 第 1 层:整点网格(每小时一格,格底一条灰线) */
|
||||||
@@ -815,7 +818,6 @@ struct Widget4x4Card {
|
|||||||
.width('100%')
|
.width('100%')
|
||||||
.height(this.w4BlockVp(b))
|
.height(this.w4BlockVp(b))
|
||||||
.constraintSize({ minHeight: 14 })
|
.constraintSize({ minHeight: 14 })
|
||||||
.onClick(() => this.openApp())
|
|
||||||
}, (b: TBlock) => `b_${r.key}_${b.eventKey}`)
|
}, (b: TBlock) => `b_${r.key}_${b.eventKey}`)
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
|
|||||||
@@ -384,7 +384,9 @@ struct Widget6x4Card {
|
|||||||
return h < 10 ? `0${h}:00` : `${h}:00`;
|
return h < 10 ? `0${h}:00` : `${h}:00`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 右上角添加按钮:拉起 App 直接进入新建日程页(兄弟节点布局,不冒泡) */
|
/** 右上角添加按钮:拉起 App 直接进入新建日程页。
|
||||||
|
* ⭐ 无需阻止冒泡:ArkUI 的 `onClick` 是**非冒泡**事件,父子同绑时**子组件优先**,
|
||||||
|
* 故点 + 不会连带触发根容器的"打开首页"。 */
|
||||||
@Builder
|
@Builder
|
||||||
addButton() {
|
addButton() {
|
||||||
Button() {
|
Button() {
|
||||||
@@ -439,6 +441,7 @@ struct Widget6x4Card {
|
|||||||
.borderRadius(11)
|
.borderRadius(11)
|
||||||
.padding(0)
|
.padding(0)
|
||||||
.backgroundColor('#F2F3F5')
|
.backgroundColor('#F2F3F5')
|
||||||
|
// ⭐ 无需阻止冒泡:onClick 非冒泡、子组件优先 → 点翻页不会连带打开 App
|
||||||
.onClick(() => this.page(act))
|
.onClick(() => this.page(act))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,6 +460,7 @@ struct Widget6x4Card {
|
|||||||
.borderRadius(11)
|
.borderRadius(11)
|
||||||
.padding(0)
|
.padding(0)
|
||||||
.backgroundColor('#007DFF')
|
.backgroundColor('#007DFF')
|
||||||
|
// ⭐ 无需阻止冒泡:onClick 非冒泡、子组件优先
|
||||||
.onClick(() => this.page('today'))
|
.onClick(() => this.page('today'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -549,7 +553,6 @@ struct Widget6x4Card {
|
|||||||
.width('100%')
|
.width('100%')
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.justifyContent(FlexAlign.Center)
|
.justifyContent(FlexAlign.Center)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
} else {
|
} else {
|
||||||
List({ space: 4 }) {
|
List({ space: 4 }) {
|
||||||
ForEach(this.parseList(), (item: LItem6) => {
|
ForEach(this.parseList(), (item: LItem6) => {
|
||||||
@@ -563,7 +566,6 @@ struct Widget6x4Card {
|
|||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.scrollBar(BarState.Auto)
|
.scrollBar(BarState.Auto)
|
||||||
.cachedCount(8)
|
.cachedCount(8)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +586,6 @@ struct Widget6x4Card {
|
|||||||
}
|
}
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.alignItems(HorizontalAlign.Start)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
Text(`${this.dayCount} 条`)
|
Text(`${this.dayCount} 条`)
|
||||||
.fontSize(10)
|
.fontSize(10)
|
||||||
.fontColor('#B0B0B0')
|
.fontColor('#B0B0B0')
|
||||||
@@ -629,7 +630,6 @@ struct Widget6x4Card {
|
|||||||
.padding({ left: 6, right: 6 })
|
.padding({ left: 6, right: 6 })
|
||||||
.borderRadius(6)
|
.borderRadius(6)
|
||||||
.backgroundColor(a.color)
|
.backgroundColor(a.color)
|
||||||
.onClick(() => this.openApp())
|
|
||||||
}, (a: TAllDay6, idx: number) => `ad_${idx}_${a.eventKey}`)
|
}, (a: TAllDay6, idx: number) => `ad_${idx}_${a.eventKey}`)
|
||||||
if (this.w6AllDayRest() > 0) {
|
if (this.w6AllDayRest() > 0) {
|
||||||
Text(`还有 ${this.w6AllDayRest()} 个全天日程`)
|
Text(`还有 ${this.w6AllDayRest()} 个全天日程`)
|
||||||
@@ -689,6 +689,9 @@ struct Widget6x4Card {
|
|||||||
.padding(12)
|
.padding(12)
|
||||||
.backgroundColor('#FFFFFF')
|
.backgroundColor('#FFFFFF')
|
||||||
.borderRadius(16)
|
.borderRadius(16)
|
||||||
|
// ⭐ 整卡可点:空白处也能进 App 并定位到当前显示日。
|
||||||
|
// ⚠️ onClick 是**非冒泡**事件且**子组件优先** → 内部的 ‹ › 今 + 按钮不会被这里抢走
|
||||||
|
.onClick(() => this.openApp())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 第 1 层:整点网格(每小时一格,格底一条灰线) */
|
/** 第 1 层:整点网格(每小时一格,格底一条灰线) */
|
||||||
@@ -814,7 +817,6 @@ struct Widget6x4Card {
|
|||||||
.width('100%')
|
.width('100%')
|
||||||
.height(this.w6BlockVp(b))
|
.height(this.w6BlockVp(b))
|
||||||
.constraintSize({ minHeight: 16 })
|
.constraintSize({ minHeight: 16 })
|
||||||
.onClick(() => this.openApp())
|
|
||||||
}, (b: TBlock6) => `b_${r.key}_${b.eventKey}`)
|
}, (b: TBlock6) => `b_${r.key}_${b.eventKey}`)
|
||||||
}
|
}
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user