【无标题】

定义:半模态页面是一种多形态弹窗组件,支持在设备不同宽度下显示不同样式。用户可通过侧滑、点击蒙层/关闭按钮、下拉手势关闭页面,常用于扩展内容展示(如抽屉式面板)。

核心特性

  1. 多形态适配:根据设备宽度自动调整样式。
  2. 灵活关闭方式:支持侧滑、蒙层点击、按钮关闭、下拉关闭。
  3. 交互控制:嵌套滚动支持、多档位高度、生命周期管理。

例如图中所示:


二、核心 API:bindSheet()

方法签名
bindSheet(
  isShow: Optional<boolean>,  // 控制显示/隐藏(支持 $$ 双向绑定)
  builder: CustomBuilder,     // 自定义内容构建器
  options?: SheetOptions      // 配置项(可选)
): T
参数说明

参数

类型

必填

说明

isShow

Optional<boolean>

控制显示状态:
- true:显示
- false:隐藏

builder

CustomBuilder

自定义半模态内容(通过 @Builder 定义)

options

SheetOptions

配置半模态属性(高度、背景色、生命周期等)


三、基础使用示例

场景:点击按钮弹出半模态页面
@Entry
@Component
struct SheetExample {
  @State isShow: boolean = false;

  // 自定义半模态内容
  @Builder
  myBuilder() {
    Column() {
      Button("关闭面板")
        .onClick(() => this.isShow = false) // 点击关闭
    }
    .width('100%').height('100%')
  }

  build() {
    Column() {
      Button("打开半模态")
        .onClick(() => this.isShow = true)
        .bindSheet(
          $$this.isShow, 
          this.myBuilder(), 
          { height: 300, backgroundColor: Color.Gray }
        )
    }
  }
}

通过.bindSheet()方法将半模态页面绑定到Button组件上,其中:

  • $$this.isShow 实现双向数据绑定,自动同步半模态的显示状态
  • this.myBuilder() 使用@Builder装饰器定义的UI构建函数,描述半模态内部内容结构

运行截图:


四、嵌套滚动交互

当半模态容器内包含可滚动组件(如List)时,手势操作可能同时影响两个层级:

  1. 容器层级:面板高度调整/关闭操作
  2. 内容层级:内部组件滚动

通过嵌套滚动交互规则,可精确控制手势响应的优先级:

  • 上滑/下滑时决定优先处理面板操作还是内容滚动
  • 根据内容当前位置动态调整响应策略(顶部/中间/底部)
  • 使用nestedScroll()配置实现精细控制
交互规则

当半模态内部有可滚动组件(如 List)时:

  1. 内容在顶部
    • 上滑 → 优先扩展面板高度(若有更高档位)
    • 下滑 → 优先收缩面板或关闭
  1. 内容在中间
    • 优先滚动内容,直到内容到达顶部/底部
  1. 内容在底部
    • 上滑 → 内容回弹(不切换档位)
    • 下滑 → 滚动内容到顶部
关键配置

在内部滚动组件设置 嵌套滚动属性

List() {
  // 列表内容...
}
.nestedScroll({
  scrollForward: NestedScrollMode.PARENT_FIRST,  // 上滑优先处理面板
  scrollBackward: NestedScrollMode.SELF_FIRST    // 下滑优先处理列表
})
完整示例
@Entry
@Component
struct NestedScrollSheet {
  @State isShow: boolean = false;
  private data: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

  @Builder
  sheetContent() {
    List({ space: '10vp' }) {
      ForEach(this.data, (item:number) => {
        ListItem() { Text(String(item)).fontSize(16).fontWeight(FontWeight.Bold) }
        .width('90%').height('80vp').backgroundColor('#ff53ecd9').borderRadius(10)
      })
    }
    .alignListItem(ListItemAlign.Center)
    .margin({ top: '10vp' })
    .width('100%')
    .height('100%')
    .nestedScroll({ // 关键配置
      scrollForward: NestedScrollMode.PARENT_FIRST,
      scrollBackward: NestedScrollMode.SELF_FIRST
    })
  }

  build() {
    Column() {
      Button("打开带嵌套滚动的面板")
        .onClick(() => this.isShow = true)
        .bindSheet($$this.isShow, this.sheetContent(), {
          detents: [200, 400, 600] // 定义三个高度档位
        })
    }
  }
}


五、生命周期管理

半模态提供完整的生命周期回调:

回调函数

触发时机

典型用途

onWillAppear

面板显示前(动画开始前)

初始化数据

onAppear

面板显示后(动画结束后)

触发动态操作

onWillDisappear

面板关闭前(动画开始前)

数据备份/清理

onDisappear

面板关闭后(动画结束后)

资源释放

使用示例
Button("打开面板")
  .bindSheet($$this.isShow, this.myBuilder(), {
    onWillAppear: () => console.log("即将显示"),
    onAppear: () => console.log("已显示"),
    onWillDisappear: () => console.log("即将关闭"),
    onDisappear: () => console.log("已关闭")
  })

六、高级功能

1. 多档位高度(Detents)

支持预定义多个高度档位,用户可拖拽切换:

bindSheet($$this.isShow, builder, {
  detents: [
    SheetSize.SMALL,  // 系统小尺寸
    SheetSize.MEDIUM, // 系统中尺寸
    450,              // 自定义高度(vp)
    SheetSize.LARGE   // 系统大尺寸
  ]
})
2. 二次确认关闭

防止误触关闭,需用户确认:

bindSheet($$this.isShow, builder, {
// 第一步:声明onWillDismiss回调
onWillDismiss: ((DismissSheetAction: DismissSheetAction) => {
// 第二步:确认二次回调交互能力,此处用AlertDialog提示 "是否需要关闭半模态"
  this.getUIContext().showAlertDialog(
    {
      message: '是否选择关闭半模态',
      autoCancel: true,
      alignment: DialogAlignment.Bottom,
      gridCount: 4,
      offset: { dx: 0, dy: -20 },
      primaryButton: {
        value: 'cancel',
        action: () => {
          console.info('Callback when the cancel button is clicked');
        }
      },
      secondaryButton: {
        enabled: true,
        defaultFocus: true,
        style: DialogButtonStyle.HIGHLIGHT,
        value: 'ok',
        // 第三步:确认关闭半模态逻辑所在,此处为AlertDialog的Button回调
        action: () => {
          // 第四步:上述第三步逻辑触发的时候,调用dismiss()关闭半模态
          DismissSheetAction.dismiss();
          console.info('Callback when the ok button is clicked');
        }
      },
      cancel: () => {
        console.info('AlertDialog Closed callbacks');
      }
    }
  )
})
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值