ArkUI bindSheet:半屏一拉起,任务别变成新页面
【摘要】 今天我们用 bindSheet 做一个半模态任务面板。 半模态适合处理短任务。比如整理草稿、补标签、选择分享范围,这些事不一定值得开一个完整页面,但又比一句提示复杂一点。我们这篇只做一个触发按钮和一个面板,先把最常用的结构跑通。 准备一个显示开关 bindSheet 需要一个布尔值控制显示和隐藏。 按钮点击时把它改成
ArkUI bindSheet:半屏一拉起,任务别变成新页面
今天我们用 bindSheet 做一个半模态任务面板。
半模态适合处理短任务。比如整理草稿、补标签、选择分享范围,这些事不一定值得开一个完整页面,但又比一句提示复杂一点。我们这篇只做一个触发按钮和一个面板,先把最常用的结构跑通。
准备一个显示开关
bindSheet 需要一个布尔值控制显示和隐藏。
@State showSheet: boolean = false
按钮点击时把它改成 true,面板里的“完成并收起”按钮再改回 false。这一步只是控制半模态显隐,不展开状态管理。
还有一个很容易踩的点:用户也可能用半模态自带关闭按钮、拖拽或蒙层关闭面板。面板关了以后,我们也要把 showSheet 同步回 false,否则下次点击还是 true -> true,界面就不会重新拉起。
写面板内容
面板内容放进一个 builder。
@Builder
sheetContent() {
Column({ space: 18 }) {
Text('整理这篇草稿')
Button('完成并收起')
.onClick(() => {
this.showSheet = false
})
}
}
我们把关闭按钮放在面板内部,是为了让用户看到明确的收尾动作。半模态也支持拖动和关闭入口,但案例里保留一个按钮更直观。
绑定到一个按钮上
真正绑定时,用 bindSheet。
Button('打开半模态任务面板')
.onClick(() => {
this.showSheet = true
})
.bindSheet(this.showSheet, this.sheetContent, {
height: SheetSize.MEDIUM,
dragBar: true,
showClose: true,
detents: [SheetSize.MEDIUM, SheetSize.LARGE],
maskColor: '#66000000',
onDisappear: () => {
this.showSheet = false
}
})
这里故意只给一个按钮绑定一个半模态。一个节点上挂太多面板,后面维护起来很容易乱。
height 决定初始高度,detents 决定可停靠高度。dragBar 和 showClose 让用户知道这个面板可以被收起。maskColor 给底层页面加一层遮罩,让当前重点更明确。onDisappear 负责把页面里的显隐状态同步回来,避免关闭后再次点击没有反应。
你可以想一下自己的页面:有没有哪个操作只是临时补充几项信息,却被做成了完整页面?这种场景很适合先试试半模态。
完整代码
@Entry
@Component
struct ArkUIBindSheetDemo {
@State showSheet: boolean = false
@Builder
sectionTitle(title: string, desc: string) {
Column({ space: 6 }) {
Text(title)
.fontSize(19)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text(desc)
.fontSize(13)
.fontColor('#6B7280')
.lineHeight(20)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
}
@Builder
sheetContent() {
Column({ space: 18 }) {
Column({ space: 8 }) {
Text('整理这篇草稿')
.fontSize(22)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text('半模态适合处理一个临时任务。底层页面还在,用户知道自己从哪里来。')
.fontSize(14)
.fontColor('#6B7280')
.lineHeight(22)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
Column({ space: 10 }) {
this.taskRow('检查标题', '标题要让用户知道这次面板在处理什么。', '#2563EB')
this.taskRow('补充标签', '短任务放在这里,比跳到新页面更轻。', '#0F766E')
this.taskRow('确认发布前状态', '任务完成后可以直接收起面板。', '#C2410C')
}
.width('100%')
Button('完成并收起')
.width('100%')
.height(44)
.borderRadius(22)
.fontColor('#FFFFFF')
.backgroundColor('#111827')
.onClick(() => {
this.showSheet = false
})
}
.width('100%')
.padding({ left: 22, right: 22, top: 18, bottom: 24 })
.backgroundColor('#FFFFFF')
}
@Builder
taskRow(title: string, desc: string, color: string) {
Row({ space: 12 }) {
Text(title.substring(0, 1))
.fontSize(15)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
.textAlign(TextAlign.Center)
.width(34)
.height(34)
.borderRadius(17)
.backgroundColor(color)
Column({ space: 4 }) {
Text(title)
.fontSize(15)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text(desc)
.fontSize(12)
.fontColor('#6B7280')
.lineHeight(18)
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.padding(12)
.borderRadius(12)
.backgroundColor('#F8FAFC')
.border({ width: 1, color: '#E5E7EB' })
}
build() {
Scroll() {
Column({ space: 22 }) {
Column({ space: 8 }) {
Text('ArkUI bindSheet')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text('半屏一拉起,任务别变成新页面')
.fontSize(16)
.fontColor('#4B5563')
Text('半模态适合处理短任务。它保留底层页面的上下文,比新开一个完整页面更轻。')
.fontSize(14)
.fontColor('#6B7280')
.lineHeight(22)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
this.sectionTitle('一个按钮绑定一个半模态', '这里故意只放一个触发点,避免同一个节点挂多个面板导致关系混乱。')
Column({ space: 14 }) {
Text('点击按钮后,面板以中等高度出现,并提供拖拽条、关闭按钮和两个停靠高度。')
.fontSize(14)
.fontColor('#4B5563')
.lineHeight(22)
.width('100%')
Button('打开半模态任务面板')
.fontSize(14)
.fontColor('#FFFFFF')
.backgroundColor('#2563EB')
.borderRadius(20)
.height(40)
.padding({ left: 20, right: 20 })
.onClick(() => {
this.showSheet = true
})
.bindSheet(this.showSheet, this.sheetContent, {
height: SheetSize.MEDIUM,
dragBar: true,
showClose: true,
detents: [SheetSize.MEDIUM, SheetSize.LARGE],
maskColor: '#66000000',
onDisappear: () => {
this.showSheet = false
}
})
}
.width('100%')
.padding(16)
.borderRadius(14)
.backgroundColor('#FFFFFF')
.border({ width: 1, color: '#E5E7EB' })
.alignItems(HorizontalAlign.Start)
this.sectionTitle('几个参数先看懂', 'height 决定初始高度,detents 决定可停靠高度,dragBar 和 showClose 负责基础关闭体验。')
Column({ space: 10 }) {
this.taskRow('SheetSize.MEDIUM', '初始展示半屏左右,适合临时任务。', '#2563EB')
this.taskRow('detents', '允许用户把面板拖到另一个高度。', '#0F766E')
this.taskRow('maskColor', '给底层页面一层遮罩,提示当前重点在面板里。', '#C2410C')
}
.width('100%')
}
.width('100%')
.padding(24)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.height('100%')
.backgroundColor('#F8FAFC')
}
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)