style(粘贴/待办卡片): 粘贴按钮与「地图」同款外观;待办卡片对齐 App 内样式
## 1. 粘贴按钮改成与「地图」一样 原来只用系统默认样式,与旁边的「地图」按钮风格割裂。 安全控件支持 fontSize / fontColor / backgroundColor / borderRadius / padding (见 security_component.d.ts),所以可以完全对齐: 13 号字 · brand_text 色 · card_bg 底 · 圆角 12 · 高 44 与「地图」并排、同高、同样留白。文字内容由系统枚举决定 (`PasteDescription` 只有 `PASTE` 一个值,即「粘贴」)。 真机实测两个按钮并排: PasteButton [680,1802][837,1940] 文字='粘贴' Text(地图) [862,1802][1018,1940] 文字='地图' 同高同排,13 号字。 ## 2. 待办卡片列表对齐 App 内样式 用户指出:卡片里的待办样式(灰勾选框 + 色条)与 App 内待办列表不一致, 两套设计没必要。App 内 `Index.todoRow` 的样式是: - 勾选圈 **颜色跟随日历本**(未完成=空心环 2px,已完成=实心+✓) - 标题 15 号,已完成加删除线 - 副行 12 号 = 截止时间 · 日历本 - 行背景 card_bg,圆角 12,1px 边框 卡片侧改为同一套结构,只按卡片尺寸把号数收小: | 卡片 | 圈 | 标题 | 副行 | |---|---|---|---| | 4×4 / 6×4 | 18 | 13 | 10 | | 2×4 | 16 | 12 | 9 | 去掉原来的色条和灰色勾选框 —— 用日历本色圆圈,与 App 内视觉一致。 数据侧给 `TodoCardItem` 增加 `subText`(「截止时间 · 日历本」拼好的副行文字), 由数据层统一拼接,避免三张卡片各拼一遍导致不一致。 ## 一致性校验 逐行 diff 确认 4×4 与 6×4 的 `todoRow` **完全一致**(归一化类型名后逐字符相等); 2×4 结构相同,仅尺寸小一档。 ## 编译 `BUILD SUCCESSFUL` ## 未验证 粘贴按钮已确认渲染与布局(dump 坐标/文字),视觉观感需上机目视; 待办卡片需删除桌面旧卡片后重新添加才能看到新样式。
This commit is contained in:
@@ -43,6 +43,11 @@ export class TodoCardItem {
|
||||
title: string = '';
|
||||
/** 截止时间文字:'今天 18:00' / '明天' / '无日期' */
|
||||
dueText: string = '';
|
||||
/**
|
||||
* 副行文字:截止时间 · 日历本(与 App 内 todoSubtitle 同款呈现)。
|
||||
* 在数据侧拼好,卡片侧直接显示,避免各卡片各拼一遍导致不一致。
|
||||
*/
|
||||
subText: string = '';
|
||||
color: string = '#007DFF';
|
||||
calName: string = '';
|
||||
/** 是否已完成(已完成的不出现在待办卡片列表里,此字段留作扩展) */
|
||||
@@ -521,6 +526,8 @@ export class CardDataService {
|
||||
it.dueText = `${due.getMonth() + 1}/${due.getDate()}${timePart}`;
|
||||
}
|
||||
}
|
||||
// 副行:截止时间 · 日历本(本名为空时只显示截止时间)
|
||||
it.subText = it.calName !== '' ? `${it.dueText} · ${it.calName}` : it.dueText;
|
||||
items.push(it);
|
||||
}
|
||||
|
||||
|
||||
@@ -1750,16 +1750,17 @@ struct EventEditPage {
|
||||
// (无需申请 READ_PASTEBOARD —— 那是受限权限,普通应用申请会被拒)
|
||||
//
|
||||
// ⚠️ icon/text/buttonType **只能走构造参数**,写成链式属性会编译报错。
|
||||
// ⚠️ 不要自定义背景色:SDK 明确把"字体颜色与背景相近"列为样式违规
|
||||
// (错误码 2),会让人字形灰淡难辨、甚至授权失败。
|
||||
// 交给系统默认样式即可,只调尺寸与圆角。
|
||||
// 文字内容由系统枚举决定(PasteDescription 只有 PASTE 一个值,即「粘贴」)。
|
||||
// 外观与右边的「地图」按钮保持一致:同字号、同色、同底色、同圆角、同高度。
|
||||
PasteButton({
|
||||
icon: PasteIconStyle.LINES,
|
||||
text: PasteDescription.PASTE,
|
||||
buttonType: ButtonType.Capsule
|
||||
})
|
||||
.fontSize(13)
|
||||
.fontColor($r('app.color.brand_text'))
|
||||
.backgroundColor($r('app.color.card_bg'))
|
||||
.height(44)
|
||||
.padding({ left: 10, right: 14 })
|
||||
.padding({ left: 12, right: 12 })
|
||||
.borderRadius(12)
|
||||
.onClick(() => {
|
||||
this.pastePlace();
|
||||
|
||||
@@ -8,6 +8,8 @@ class TodoItem2x4 {
|
||||
id: number = 0;
|
||||
title: string = '';
|
||||
dueText: string = '';
|
||||
/** 副行:截止时间 · 日历本 */
|
||||
subText: string = '';
|
||||
color: string = '#007DFF';
|
||||
calName: string = '';
|
||||
completed: boolean = false;
|
||||
@@ -78,45 +80,46 @@ struct TodoWidget2x4Card {
|
||||
});
|
||||
}
|
||||
|
||||
/** 圆形勾选框(未完成状态:空心圆) */
|
||||
@Builder
|
||||
checkbox(id: number) {
|
||||
// 同 4x4:不用 SDK 26 的 Circle().stroke(),改用 border 圆角
|
||||
Column()
|
||||
.width(18)
|
||||
.height(18)
|
||||
.borderRadius(9)
|
||||
.border({ width: 1.5, color: '#B0B0B0' })
|
||||
.backgroundColor(Color.Transparent)
|
||||
.onClick(() => this.checkTodo(id))
|
||||
}
|
||||
|
||||
/** 右侧单条待办:勾选框 + 标题 + 截止时间 */
|
||||
/**
|
||||
* 单条待办:与 4×4 / 6×4 同款结构(圆圈用日历本色 + 标题 + 副行),
|
||||
* 尺寸再收一档 —— 2×4 只有 2 格高,圈 16 / 标题 12 / 副行 9。
|
||||
*/
|
||||
@Builder
|
||||
todoRow(item: TodoItem2x4) {
|
||||
Row({ space: 6 }) {
|
||||
this.checkbox(item.id)
|
||||
// 勾选圈:颜色用日历本色,点击即完成
|
||||
Row() {
|
||||
Text('')
|
||||
.width(16)
|
||||
.height(16)
|
||||
.borderRadius(8)
|
||||
.border({ width: 2, color: item.color })
|
||||
}
|
||||
.padding({ right: 2 })
|
||||
.onClick(() => {
|
||||
this.checkTodo(item.id);
|
||||
})
|
||||
|
||||
Column({ space: 1 }) {
|
||||
// 标题限 1 行:2x4 高度只有 2 格,2 行会让一屏只放得下 1 条多,滑动失去意义
|
||||
Text(item.title)
|
||||
.fontSize(12)
|
||||
.fontColor('#1A1A1A')
|
||||
.maxLines(1)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.width('100%')
|
||||
Text(item.dueText)
|
||||
Text(item.subText)
|
||||
.fontSize(9)
|
||||
.fontColor(item.dueText.indexOf('逾期') >= 0 ? '#FF3B30' : '#8A8A8A')
|
||||
.fontColor('#8A8A8A')
|
||||
.maxLines(1)
|
||||
.width('100%')
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
}
|
||||
.layoutWeight(1)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
}
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.width('100%')
|
||||
.padding({ left: 2, right: 6, top: 4, bottom: 4 })
|
||||
.borderRadius(8)
|
||||
.padding({ left: 4, right: 8, top: 5, bottom: 5 })
|
||||
.borderRadius(9)
|
||||
.backgroundColor('#F5F7FA')
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ class TodoItem4x4 {
|
||||
id: number = 0;
|
||||
title: string = '';
|
||||
dueText: string = '';
|
||||
/** 副行:截止时间 · 日历本 */
|
||||
subText: string = '';
|
||||
color: string = '#007DFF';
|
||||
calName: string = '';
|
||||
completed: boolean = false;
|
||||
@@ -83,43 +85,48 @@ struct TodoWidget4x4Card {
|
||||
.onClick(() => this.checkTodo(id))
|
||||
}
|
||||
|
||||
/** 单条待办:勾选框 + 左色竖条 + 标题/截止时间 + 日历本名 */
|
||||
/**
|
||||
* 单条待办:与 App 内 Index.todoRow 同款结构 ——
|
||||
* 圆圈(颜色跟随日历本)+ 标题 + 副行「截止时间 · 日历本」
|
||||
*
|
||||
* ⚠️ 未完成=空心环、已完成=实心+✓,这套语义与 App 内一致;
|
||||
* 卡片上只显示未完成,所以这里主要是空心环。
|
||||
* ⚠️ 4×4 与 6×4 的 todoRow 必须**完全一致**(用户要求),改一处要同步另一处。
|
||||
*/
|
||||
@Builder
|
||||
todoRow(item: TodoItem4x4) {
|
||||
Row({ space: 8 }) {
|
||||
this.checkbox(item.id)
|
||||
Column()
|
||||
.width(3)
|
||||
.height(32)
|
||||
.borderRadius(2)
|
||||
.backgroundColor(item.color)
|
||||
Column({ space: 3 }) {
|
||||
// 勾选圈:颜色用日历本色(与 App 内一致),点击即完成
|
||||
Row() {
|
||||
Text('')
|
||||
.width(18)
|
||||
.height(18)
|
||||
.borderRadius(9)
|
||||
.border({ width: 2, color: item.color })
|
||||
}
|
||||
.padding({ right: 2 })
|
||||
.onClick(() => {
|
||||
this.checkTodo(item.id);
|
||||
})
|
||||
|
||||
Column({ space: 2 }) {
|
||||
Text(item.title)
|
||||
.fontSize(13)
|
||||
.fontColor('#1A1A1A')
|
||||
.maxLines(2)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
Row({ space: 6 }) {
|
||||
Text(item.dueText)
|
||||
.fontSize(10)
|
||||
.fontColor(item.dueText.indexOf('逾期') >= 0 ? '#FF3B30' : '#8A8A8A')
|
||||
.maxLines(1)
|
||||
if (item.calName !== '') {
|
||||
Text(item.calName)
|
||||
.fontSize(10)
|
||||
.fontColor(item.color)
|
||||
.maxLines(1)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.constraintSize({ maxWidth: '55%' })
|
||||
Text(item.subText)
|
||||
.fontSize(10)
|
||||
.fontColor('#8A8A8A')
|
||||
.maxLines(1)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
}
|
||||
}
|
||||
}
|
||||
.layoutWeight(1)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
.layoutWeight(1)
|
||||
}
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.width('100%')
|
||||
.padding({ left: 4, right: 10, top: 6, bottom: 6 })
|
||||
.padding({ left: 6, right: 8, top: 6, bottom: 6 })
|
||||
.borderRadius(10)
|
||||
.backgroundColor('#F5F7FA')
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ class TodoItem6x4 {
|
||||
id: number = 0;
|
||||
title: string = '';
|
||||
dueText: string = '';
|
||||
/** 副行:截止时间 · 日历本 */
|
||||
subText: string = '';
|
||||
color: string = '#007DFF';
|
||||
calName: string = '';
|
||||
completed: boolean = false;
|
||||
@@ -84,49 +86,47 @@ struct TodoWidget6x4Card {
|
||||
}
|
||||
|
||||
/**
|
||||
* 单条待办:勾选框 + 色条 + 标题 + 副行(截止时间 · 日历本)。
|
||||
* 单条待办:与 App 内 Index.todoRow 同款结构 ——
|
||||
* 圆圈(颜色跟随日历本)+ 标题 + 副行「截止时间 · 日历本」
|
||||
*
|
||||
* ⚠️ 与 TodoWidget4x4 的 todoRow **保持完全一致**(用户要求两个卡片显示效果一模一样)。
|
||||
* 改这里必须同步改那边,否则又会不一致。
|
||||
* 选这个结构而不是"独立列 + 固定宽度":标题 layoutWeight(1) 能吃满剩余宽度,
|
||||
* 在窄卡片里也不会被挤出屏幕。
|
||||
* ⚠️ 未完成=空心环、已完成=实心+✓,这套语义与 App 内一致;
|
||||
* 卡片上只显示未完成,所以这里主要是空心环。
|
||||
* ⚠️ 4×4 与 6×4 的 todoRow 必须**完全一致**(用户要求),改一处要同步另一处。
|
||||
*/
|
||||
@Builder
|
||||
todoRow(item: TodoItem6x4) {
|
||||
Row({ space: 8 }) {
|
||||
this.checkbox(item.id)
|
||||
Column()
|
||||
.width(3)
|
||||
.height(32)
|
||||
.borderRadius(2)
|
||||
.backgroundColor(item.color)
|
||||
Column({ space: 3 }) {
|
||||
// 勾选圈:颜色用日历本色(与 App 内一致),点击即完成
|
||||
Row() {
|
||||
Text('')
|
||||
.width(18)
|
||||
.height(18)
|
||||
.borderRadius(9)
|
||||
.border({ width: 2, color: item.color })
|
||||
}
|
||||
.padding({ right: 2 })
|
||||
.onClick(() => {
|
||||
this.checkTodo(item.id);
|
||||
})
|
||||
|
||||
Column({ space: 2 }) {
|
||||
Text(item.title)
|
||||
.fontSize(13)
|
||||
.fontColor('#1A1A1A')
|
||||
.maxLines(2)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
Row({ space: 6 }) {
|
||||
Text(item.dueText)
|
||||
.fontSize(10)
|
||||
.fontColor(item.dueText.indexOf('逾期') >= 0 ? '#FF3B30' : '#8A8A8A')
|
||||
.maxLines(1)
|
||||
if (item.calName !== '') {
|
||||
Text(item.calName)
|
||||
.fontSize(10)
|
||||
.fontColor(item.color)
|
||||
.maxLines(1)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.constraintSize({ maxWidth: '55%' })
|
||||
Text(item.subText)
|
||||
.fontSize(10)
|
||||
.fontColor('#8A8A8A')
|
||||
.maxLines(1)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
}
|
||||
}
|
||||
}
|
||||
.layoutWeight(1)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
.layoutWeight(1)
|
||||
}
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.width('100%')
|
||||
.padding({ left: 4, right: 10, top: 6, bottom: 6 })
|
||||
.padding({ left: 6, right: 8, top: 6, bottom: 6 })
|
||||
.borderRadius(10)
|
||||
.backgroundColor('#F5F7FA')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user