本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
bindSheet
核心功能bindSheet
是鸿蒙中用于 底部弹窗(Bottom Sheet)数据绑定 的关键方法,通常与 @State
或 @Link
装饰器配合使用,实现动态内容更新。主要应用于:
@Entry
@Component
struct BindSheetExample {
@State sheetData: string[] = ['选项A', '选项B', '选项C'];
@State isShowSheet: boolean = false;
build() {
Column() {
Button('打开底部弹窗')
.onClick(() => {
this.isShowSheet = true;
})
}
.bindSheet(
this.isShowSheet, // 控制显示/隐藏
this.sheetData, // 绑定数据源
(item: string) => {
// 渲染每一项
Text(item)
.fontSize(16)
.margin(10)
}
)
}
}
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
isShow |
boolean |
是 | 控制弹窗显示/隐藏 |
data |
Array |
是 | 数据源数组 |
itemBuilder |
(item: any) => void |
是 | 每一项的UI构建函数 |
@State sheetData: { id: number, name: string }[] = [
{ id: 1, name: '苹果' },
{ id: 2, name: '香蕉' }
];
// 点击添加新项
addItem() {
this.sheetData.push({ id: Date.now(), name: '新水果' });
this.sheetData = [...this.sheetData]; // 必须更新引用触发刷新
}
build() {
Column() {
Button('添加选项')
.onClick(() => this.addItem())
}
.bindSheet(
this.isShowSheet,
this.sheetData,
(item) => {
Text(`${item.id}. ${item.name}`)
.onClick(() => {
console.log(`选择了: ${item.name}`);
this.isShowSheet = false;
})
}
)
}
.bindSheet(
this.isShowSheet,
this.sheetData,
(item) => Text(item),
{
backgroundColor: '#F5F5F5', // 背景色
height: '50%', // 弹窗高度
borderRadius: 20, // 圆角
dragBar: true // 显示拖动条
}
)
.bindSheet(
this.isShowSheet,
this.sheetData,
(item) => Text(item),
{
onAppear: () => console.log('弹窗打开'),
onDisappear: () => console.log('弹窗关闭'),
onDismiss: (reason: SheetDismissReason) => {
// 处理关闭原因(点击背景/拖动关闭等)
console.log(`关闭原因: ${reason}`);
}
}
)
@Entry
@Component
struct MultiSelectSheet {
@State isShow: boolean = false;
@State selectedItems: string[] = [];
@State allItems: string[] = ['红色', '绿色', '蓝色', '黄色'];
toggleSelect(item: string) {
if (this.selectedItems.includes(item)) {
this.selectedItems = this.selectedItems.filter(i => i !== item);
} else {
this.selectedItems = [...this.selectedItems, item];
}
}
build() {
Column() {
Text(`已选: ${this.selectedItems.join(',')}`)
.margin(10)
Button('选择颜色')
.onClick(() => this.isShow = true)
}
.bindSheet(
this.isShow,
this.allItems,
(item) => {
Row() {
Text(item)
.fontSize(18)
if (this.selectedItems.includes(item)) {
Image($r('app.media.checked'))
.width(20)
.margin(10)
}
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.onClick(() => this.toggleSelect(item))
},
{
height: '60%',
onDismiss: () => {
console.log('最终选择:', this.selectedItems);
}
}
)
}
}
@State currentPage: number = 1;
@State loadedData: string[] = [];
loadMore() {
// 模拟分页请求
const newData = /* 网络请求获取数据 */;
this.loadedData = [...this.loadedData, ...newData];
}
.bindSheet(
this.isShowSheet,
this.loadedData,
(item) => Text(item),
{
onReachEnd: () => {
this.currentPage++;
this.loadMore();
}
}
)
// 定义可复用项组件
@Component
struct SheetItem {
@Prop item: string;
build() {
Text(this.item)
.fontSize(16)
.backgroundColor('#EEE')
.margin(5)
}
}
// 在bindSheet中使用
.bindSheet(
this.isShowSheet,
this.sheetData,
(item) => {
SheetItem({ item })
}
)
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
isShow |
boolean |
false | 控制显示/隐藏 |
data |
Array |
[] | 数据源数组 |
itemBuilder |
(item: any) => void |
- | 每项渲染函数 |
options |
SheetOptions |
{} | 可选配置项 |
SheetOptions 配置项:
interface SheetOptions {
height?: Length; // 弹窗高度
backgroundColor?: ResourceColor; // 背景色
dragBar?: boolean; // 是否显示拖动条
onAppear?: () => void; // 打开回调
onDisappear?: () => void; // 关闭回调
onDismiss?: (reason: SheetDismissReason) => void; // 关闭原因回调
}