删除按钮从底栏移到内容最底部(危险操作区)(#77)

用户 2026-11-05:「删除按钮不能出现在那里,因为这样太容易误触了。
删除按钮应该放在哪里?你考虑考虑。」

放在**滚动内容的最末尾**。

为什么不在底栏(原来和「保存」并排):
  ① **误触**:底栏是"保存"这种高频操作的位置,手一滑就点到删除,
     而删除**不可恢复**,一次误触 = 数据没了。
  ② **语义错位**:底栏是"我改完了、要留下这个结果"的确认区,
     不该混进"我要毁掉它"。

为什么不放顶栏:顶栏是"知道我在哪 / 怎么退出"的位置,
  在那里放删除,误触代价同样不可恢复(还紧挨着关闭按钮)。

放最底部的好处:
  · 用户得主动滚到最底才看得见 —— 低频操作不必首屏可见;
  · 纯文字(fontTiny)、无填充底色,**不像按钮**,不招手指;
  · 与正文隔一条分割线,视觉上属于"其它",不属于"操作";
  · 这是通行做法(Notion / 备忘录 / 各类设置页的删除都在最底部)。

二次确认也重做了:
  第一下「删除这个任务」→
  变成「删了就找不回来了,确定吗?」+ [确定删掉] [取消]
  原来只有"再点一次"、没有取消出口,误点后只能点别处退出
  (不明显)。现在有明确的「取消」可退。

底栏现在只剩**全宽的「保存」**,视觉上更明确:这一条就是"确认改动"。

编译通过,已装真机。
This commit is contained in:
2026-11-05 20:03:05 +08:00
parent ad63b4c89d
commit 619f800ae7
+94 -11
View File
@@ -899,6 +899,10 @@ export struct FbTaskPanel {
就会被判定为"已到底",滚不过去也看不见。 就会被判定为"已到底",滚不过去也看不见。
⇒ 底部留一块**足够高**的空白(不是 6vp 意思一下), ⇒ 底部留一块**足够高**的空白(不是 6vp 意思一下),
保证最后一行能滚到可视区中间。 */ 保证最后一行能滚到可视区中间。 */
/* #77s:删除放在**所有内容之后** —— 要滚到底才看得到,
误触概率基本为零(理由见 dangerZone 的注释)。 */
this.dangerZone()
Row().height(28) Row().height(28)
} }
.width('100%') .width('100%')
@@ -2018,6 +2022,91 @@ export struct FbTaskPanel {
.alignItems(HorizontalAlign.Start) .alignItems(HorizontalAlign.Start)
} }
/**
* 危险操作区:删除任务 —— 放在**滚动内容的最底部**。
*
* 🔴🔴 #77s(用户 2026-11-05):「删除按钮不能出现在那里,
* 因为这样太容易误触了。删除按钮应该放在哪里?你考虑考虑。」
*
* 原来它和「保存」并排钉在底栏,两个问题:
* ① **误触**:底栏是"保存"这种高频操作的位置,手一滑就点到删除,
* 而删除**不可恢复**,一次误触 = 数据没了。
* ② **语义错位**:底栏是"我改完了、要留下这个结果"的确认区,
* 不该混进"我要毁掉它"。
*
* 所以放到**滚动内容最末尾**:
* · 用户得主动滚到最底才看得见 —— 低频操作不必首屏可见;
* · 纯文字、无填充底色,不像按钮,不招手指;
* · 与正文隔一条分割线,视觉上属于"其它",不属于"操作";
* · 仍然保留**二次确认**(第一下变成「确定删掉」+「取消」)。
*
* ⚠️ 这是通行做法(Notion / 备忘录 / 各种设置页的删除都在最底部),
* 不是在发明新交互。
* ⚠️ 不放顶栏:顶栏是"知道我在哪 / 怎么退出"的位置,
* 在那里放删除,误触代价同样不可恢复。
* ⚠️ 不用红底大白按钮:那种视觉权重会把人引过去,与"低频 + 危险"正相反。
*/
@Builder
dangerZone() {
Column({ space: 0 }) {
Divider()
.color(FbColors.line)
.margin({ top: 18, bottom: 14 })
if (this.confirmDel) {
/* 第一次已点:写清后果 + 两个出口 */
Text('删了就找不回来了,确定吗?')
.fontSize(FbMetric.fontTiny)
.fontColor('#C0533F')
.width('100%')
.margin({ bottom: 8 })
Row({ space: 10 }) {
Text('确定删掉')
.fontSize(FbMetric.fontSmall)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.layoutWeight(1)
.height(40)
.backgroundColor('#C0533F')
.borderRadius(FbMetric.radiusS)
.onClick((): void => {
this.dropTask();
})
/* 「取消」必须有:误点进来要能退回去,
否则只剩"删"和"点别处"两个选择,后者不明显。 */
Text('取消')
.fontSize(FbMetric.fontSmall)
.fontColor(FbColors.muted)
.textAlign(TextAlign.Center)
.layoutWeight(1)
.height(40)
.backgroundColor(FbColors.inputBg)
.borderRadius(FbMetric.radiusS)
.onClick((): void => {
this.confirmDel = false;
this.note = '';
})
}
.width('100%')
} else {
/* 常态:一行小字,居中,不像按钮 */
Text('删除这个任务')
.fontSize(FbMetric.fontTiny)
.fontColor('#C0533F')
.textAlign(TextAlign.Center)
.width('100%')
.padding({ top: 10, bottom: 10 })
.onClick((): void => {
/* 第一下只进确认态,不删 */
this.confirmDel = true;
})
}
}
.width('100%')
}
/** 底部:编辑 / 删除 */ /** 底部:编辑 / 删除 */
@Builder @Builder
footBar() { footBar() {
@@ -2047,17 +2136,11 @@ export struct FbTaskPanel {
this.saveAll(); this.saveAll();
}) })
Text(this.confirmDel ? '确定删掉' : '删除') /* 🔴🔴 #77s(用户 2026-11-05):「删除按钮不能出现在那里,
.fontSize(FbMetric.fontSmall) 因为这样太容易误触了。」
.fontColor(this.confirmDel ? Color.White : '#C0533F') ⇒ 从底栏摘掉,移到滚动内容最末尾的 dangerZone()。
.textAlign(TextAlign.Center) 底栏只留全宽的「保存」—— 它是"确认改动"的位置,
.width(88) 不该混进"毁掉数据"的入口。 */
.height(42)
.backgroundColor(this.confirmDel ? '#C0533F' : '#FDECEC')
.borderRadius(FbMetric.radiusS)
.onClick((): void => {
this.dropTask();
})
} }
.width('100%') .width('100%')
.margin({ top: 12 }) .margin({ top: 12 })