From c4dc27ef3a77bbc16c2ac0257ce75140f104291c Mon Sep 17 00:00:00 2001 From: laoyang Date: Wed, 14 Oct 2026 22:45:51 +0800 Subject: [PATCH] =?UTF-8?q?0.0.8=EF=BC=9A=E5=8D=A1=E7=89=87=E6=95=B4?= =?UTF-8?q?=E5=8D=A1=E5=8F=AF=E7=82=B9=20=E2=80=94=E2=80=94=20=E7=82=B9?= =?UTF-8?q?=E7=A9=BA=E7=99=BD=E5=A4=84=E4=B9=9F=E8=83=BD=E8=BF=9B=20App=20?= =?UTF-8?q?=E5=B9=B6=E5=AE=9A=E4=BD=8D=E5=88=B0=E5=BD=93=E5=A4=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户反馈:卡片的空白区域点了没反应,只有落在日程/文字上才跳转。 期望:点卡片**任何位置**都进入 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(依赖上述"子组件优先"结论,需实测确认)。 --- entry/src/main/ets/pages/widget/Widget2x2.ets | 14 +++++++++----- entry/src/main/ets/pages/widget/Widget4x2.ets | 12 ++++++------ entry/src/main/ets/pages/widget/Widget4x4.ets | 14 ++++++++------ entry/src/main/ets/pages/widget/Widget6x4.ets | 14 ++++++++------ 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/entry/src/main/ets/pages/widget/Widget2x2.ets b/entry/src/main/ets/pages/widget/Widget2x2.ets index 2d6985c..908adca 100644 --- a/entry/src/main/ets/pages/widget/Widget2x2.ets +++ b/entry/src/main/ets/pages/widget/Widget2x2.ets @@ -11,8 +11,12 @@ struct Widget2x2Card { @LocalStorageProp('dateMd') dateMd: string = ''; @LocalStorageProp('weekday') weekday: string = ''; @LocalStorageProp('todayCount') todayCount: number = 0; + /** 卡片当前显示的那一天 0 点毫秒 —— 点卡片进 App 时定位到这一天 */ + @LocalStorageProp('selectedDate') selectedDate: number = 0; - /** 右上角添加按钮:拉起 App 直接进入新建日程页(阻止冒泡,避免同时打开 App 首页) */ + /** 右上角添加按钮:拉起 App 直接进入新建日程页。 + * ⭐ 无需阻止冒泡:ArkUI 的 `onClick` 是**非冒泡**事件,父子同绑时**子组件优先**, + * 故点 + 不会连带触发根容器的"打开首页"。 */ @Builder addButton() { Button() { @@ -35,12 +39,12 @@ struct Widget2x2Card { }) } - /** 卡片"打开 App":点击日期区或今日日程数区域触发;添加按钮是 header 行的兄弟节点,其点击不会冒泡到这里 */ + /** 打开 App 并**定位到卡片当前显示的那一天**(用户可能已翻到其他日期) */ private openApp(): void { postCardAction(this, { action: 'router', abilityName: 'EntryAbility', - params: {} + params: { openDate: `${this.selectedDate}` } }); } @@ -61,7 +65,6 @@ struct Widget2x2Card { } .layoutWeight(1) .alignItems(HorizontalAlign.Start) - .onClick(() => this.openApp()) this.addButton() } @@ -92,12 +95,13 @@ struct Widget2x2Card { .width('100%') .layoutWeight(1) .alignItems(VerticalAlign.Center) - .onClick(() => this.openApp()) } .width('100%') .height('100%') .padding(14) .backgroundColor('#FFFFFF') .borderRadius(16) + // ⭐ 整卡可点:空白处也能进 App 并定位到当前显示日(原来只有日期区/条数区可点) + .onClick(() => this.openApp()) } } diff --git a/entry/src/main/ets/pages/widget/Widget4x2.ets b/entry/src/main/ets/pages/widget/Widget4x2.ets index d2b8a57..89ba118 100644 --- a/entry/src/main/ets/pages/widget/Widget4x2.ets +++ b/entry/src/main/ets/pages/widget/Widget4x2.ets @@ -23,6 +23,8 @@ struct Widget4x2Card { @LocalStorageProp('lunarText') lunarText: string = ''; @LocalStorageProp('todayCount') todayCount: number = 0; @LocalStorageProp('ongoingJson') ongoingJson: string = '[]'; + /** 卡片当前显示的那一天 0 点毫秒 —— 点卡片进 App 时定位到这一天 */ + @LocalStorageProp('selectedDate') selectedDate: number = 0; /** 右侧最多渲染 2 条(数据侧已裁剪,这里再兜底截断) */ private parseOngoing(): CardItem2x4[] { @@ -57,12 +59,12 @@ struct Widget4x2Card { }) } - /** 卡片"打开 App":点击左侧日期区、今日条数区、右侧日程区触发;添加按钮是 header 行兄弟节点,不冒泡 */ + /** 打开 App 并**定位到卡片当前显示的那一天**(用户可能已翻到其他日期) */ private openApp(): void { postCardAction(this, { action: 'router', abilityName: 'EntryAbility', - params: {} + params: { openDate: `${this.selectedDate}` } }); } @@ -118,7 +120,6 @@ struct Widget4x2Card { .width('100%') .layoutWeight(1) .justifyContent(FlexAlign.Center) - .onClick(() => this.openApp()) } build() { @@ -141,7 +142,6 @@ struct Widget4x2Card { } .layoutWeight(1) .alignItems(HorizontalAlign.Start) - .onClick(() => this.openApp()) this.addButton() } @@ -173,7 +173,6 @@ struct Widget4x2Card { .width('100%') .layoutWeight(1) .alignItems(VerticalAlign.Center) - .onClick(() => this.openApp()) } .layoutWeight(1) .height('100%') @@ -197,7 +196,6 @@ struct Widget4x2Card { .width('100%') .layoutWeight(1) .justifyContent(FlexAlign.Center) - .onClick(() => this.openApp()) } } .layoutWeight(1) @@ -208,5 +206,7 @@ struct Widget4x2Card { .padding(12) .backgroundColor('#FFFFFF') .borderRadius(16) + // ⭐ 整卡可点:左右空白处也能进 App 并定位到当前显示日 + .onClick(() => this.openApp()) } } diff --git a/entry/src/main/ets/pages/widget/Widget4x4.ets b/entry/src/main/ets/pages/widget/Widget4x4.ets index a83ba36..3954228 100644 --- a/entry/src/main/ets/pages/widget/Widget4x4.ets +++ b/entry/src/main/ets/pages/widget/Widget4x4.ets @@ -387,7 +387,9 @@ struct Widget4x4Card { return h < 10 ? `0${h}` : `${h}`; } - /** 右上角添加按钮:拉起 App 直接进入新建日程页(兄弟节点布局,不冒泡到其它点击区) */ + /** 右上角添加按钮:拉起 App 直接进入新建日程页。 + * ⭐ 无需阻止冒泡:ArkUI 的 `onClick` 是**非冒泡**事件,父子同绑时**子组件优先**, + * 故点 + 不会连带触发根容器的"打开首页"。 */ @Builder addButton() { Button() { @@ -442,6 +444,7 @@ struct Widget4x4Card { .borderRadius(11) .padding(0) .backgroundColor('#F2F3F5') + // ⭐ 无需阻止冒泡:onClick 非冒泡、子组件优先 → 点翻页不会连带打开 App .onClick(() => this.page(act)) } @@ -462,6 +465,7 @@ struct Widget4x4Card { .borderRadius(11) .padding(0) .backgroundColor('#007DFF') + // ⭐ 无需阻止冒泡:onClick 非冒泡、子组件优先 .onClick(() => this.page('today')) } } @@ -554,7 +558,6 @@ struct Widget4x4Card { .width('100%') .layoutWeight(1) .justifyContent(FlexAlign.Center) - .onClick(() => this.openApp()) } else { List({ space: 4 }) { ForEach(this.parseList(), (item: LItem4) => { @@ -568,7 +571,6 @@ struct Widget4x4Card { .layoutWeight(1) .scrollBar(BarState.Auto) .cachedCount(8) - .onClick(() => this.openApp()) } } @@ -589,7 +591,6 @@ struct Widget4x4Card { } .layoutWeight(1) .alignItems(HorizontalAlign.Start) - .onClick(() => this.openApp()) this.pageBtn('›', 'next') this.sideBtn() } @@ -630,7 +631,6 @@ struct Widget4x4Card { .padding({ left: 5, right: 5 }) .borderRadius(5) .backgroundColor(a.color) - .onClick(() => this.openApp()) }, (a: TAllDay, idx: number) => `ad_${idx}_${a.eventKey}`) if (this.w4AllDayRest() > 0) { Text(`还有 ${this.w4AllDayRest()} 个全天日程`) @@ -690,6 +690,9 @@ struct Widget4x4Card { .padding(12) .backgroundColor('#FFFFFF') .borderRadius(16) + // ⭐ 整卡可点:空白处也能进 App 并定位到当前显示日。 + // ⚠️ onClick 是**非冒泡**事件且**子组件优先** → 内部的 ‹ › 今 + 按钮不会被这里抢走 + .onClick(() => this.openApp()) } /** 第 1 层:整点网格(每小时一格,格底一条灰线) */ @@ -815,7 +818,6 @@ struct Widget4x4Card { .width('100%') .height(this.w4BlockVp(b)) .constraintSize({ minHeight: 14 }) - .onClick(() => this.openApp()) }, (b: TBlock) => `b_${r.key}_${b.eventKey}`) } .layoutWeight(1) diff --git a/entry/src/main/ets/pages/widget/Widget6x4.ets b/entry/src/main/ets/pages/widget/Widget6x4.ets index 4c5b4d6..bc08dad 100644 --- a/entry/src/main/ets/pages/widget/Widget6x4.ets +++ b/entry/src/main/ets/pages/widget/Widget6x4.ets @@ -384,7 +384,9 @@ struct Widget6x4Card { return h < 10 ? `0${h}:00` : `${h}:00`; } - /** 右上角添加按钮:拉起 App 直接进入新建日程页(兄弟节点布局,不冒泡) */ + /** 右上角添加按钮:拉起 App 直接进入新建日程页。 + * ⭐ 无需阻止冒泡:ArkUI 的 `onClick` 是**非冒泡**事件,父子同绑时**子组件优先**, + * 故点 + 不会连带触发根容器的"打开首页"。 */ @Builder addButton() { Button() { @@ -439,6 +441,7 @@ struct Widget6x4Card { .borderRadius(11) .padding(0) .backgroundColor('#F2F3F5') + // ⭐ 无需阻止冒泡:onClick 非冒泡、子组件优先 → 点翻页不会连带打开 App .onClick(() => this.page(act)) } @@ -457,6 +460,7 @@ struct Widget6x4Card { .borderRadius(11) .padding(0) .backgroundColor('#007DFF') + // ⭐ 无需阻止冒泡:onClick 非冒泡、子组件优先 .onClick(() => this.page('today')) } } @@ -549,7 +553,6 @@ struct Widget6x4Card { .width('100%') .layoutWeight(1) .justifyContent(FlexAlign.Center) - .onClick(() => this.openApp()) } else { List({ space: 4 }) { ForEach(this.parseList(), (item: LItem6) => { @@ -563,7 +566,6 @@ struct Widget6x4Card { .layoutWeight(1) .scrollBar(BarState.Auto) .cachedCount(8) - .onClick(() => this.openApp()) } } @@ -584,7 +586,6 @@ struct Widget6x4Card { } .layoutWeight(1) .alignItems(HorizontalAlign.Start) - .onClick(() => this.openApp()) Text(`${this.dayCount} 条`) .fontSize(10) .fontColor('#B0B0B0') @@ -629,7 +630,6 @@ struct Widget6x4Card { .padding({ left: 6, right: 6 }) .borderRadius(6) .backgroundColor(a.color) - .onClick(() => this.openApp()) }, (a: TAllDay6, idx: number) => `ad_${idx}_${a.eventKey}`) if (this.w6AllDayRest() > 0) { Text(`还有 ${this.w6AllDayRest()} 个全天日程`) @@ -689,6 +689,9 @@ struct Widget6x4Card { .padding(12) .backgroundColor('#FFFFFF') .borderRadius(16) + // ⭐ 整卡可点:空白处也能进 App 并定位到当前显示日。 + // ⚠️ onClick 是**非冒泡**事件且**子组件优先** → 内部的 ‹ › 今 + 按钮不会被这里抢走 + .onClick(() => this.openApp()) } /** 第 1 层:整点网格(每小时一格,格底一条灰线) */ @@ -814,7 +817,6 @@ struct Widget6x4Card { .width('100%') .height(this.w6BlockVp(b)) .constraintSize({ minHeight: 16 }) - .onClick(() => this.openApp()) }, (b: TBlock6) => `b_${r.key}_${b.eventKey}`) } .layoutWeight(1)