hello大家好,这里是鸿蒙开天组,今天让我们来学习鸿蒙进阶篇-模态转场

模态转场

今天来学习模态转场,就是页面中弹出,全屏&半屏的弹框:

就像这样,模态转场主要分为半模态和全屏模态,上面的就是一个半模态。

半模态转场

核心用法

半模态顾名思义,就是半屏的模态效果(图 2)

名称

参数

参数描述

bindSheet

isShow: boolean,

builder: CustomBuilder,

options?: SheetOptions

给组件绑定半模态页面,点击后显示模态页面。

isShow: 是否显示半模态页面。

从API version 10开始,该参数支持$$双向绑定变量

builder: 配置半模态页面内容。

options: 配置半模态页面的可选属性。

核心步骤:

  1. 定义状态变量,boolean
  2. 通过 Builder 定义结构
  3. 绑定半模态 bindSheet
  4. 修改状态变量,控制显示

看起来并不复杂,让我们用一个案例来实现


@Entry
@Component
struct Page01_bindSheet {
  // 1. 定义状态变量,boolean
  @State isShow: boolean = false

  build() {
    Column() {
      Text('半模态转场')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      Button('显示半模态')
        // 3. 绑定半模态 bindSheet
        .bindSheet(this.isShow, this.sheetBuilder())
        .onClick(() => {
          // 4. 修改状态变量,控制显示
          this.isShow = true
        })
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }

  // 2.通过 Builder 定义结构
  @Builder
  sheetBuilder() {
    Column() {

    }
    .backgroundColor(Color.Pink)
    .width('100%')
    .height('100%')
  }
}

这样我们就实现了一个简单的半模态。

好的,今天的文章就到这了......什么?运行出bug了??

让我们看一下原因

原来是这里出了问题,原因在于,当我们点击这个按钮关闭半模态时,我们的isShow参数的值并没有得到改变。

说明

  • 在非双向绑定情况下,以拖拽方式关闭半模态页面不会改变isShow参数的值。
  • 为了使isShow参数值与半模态界面的状态同步,建议使用$$双向绑定isShow参数。

好的,解决方案也有了,接下来我们修改代码

// 其余代码略
.bindSheet($$this.isShow, this.sheetBuilder())

非常的简单,让我无法继续水字数...我们继续

名称

参数

参数描述

bindSheet

isShow: boolean,

builder: CustomBuilder,

options?: SheetOptions

给组件绑定半模态页面,点击后显示模态页面。

isShow: 是否显示半模态页面。

从API version 10开始,该参数支持$$双向绑定变量

builder: 配置半模态页面内容。

options: 配置半模态页面的可选属性。

这里有个小建议,$$双向绑定符号最后添加,先添加会导致我们写代码时没有提示,非常的痛苦。

注意:

  • 有不少组件也支持双向绑定的组件,也可以使用语法$$进行进行绑定
  • 当然这都是后话 =)

可选属性sheetOptions

通过第三个可选参数SheetOptions,可以对半模态的内容进行调整

其中常用属性已经标红

名称

类型

必填

描述

height

SheetSize

| Length

半模态高度,默认是LARGE。

说明:

底部弹窗竖屏时,当设置detents时,该属性设置无效。

dragBar

boolean

是否显示控制条,默认显示。

说明:

半模态面板的dentents属性设置多个不同高度并且设置生效时,默认显示控制条。否则不显示控制条。

showClose

boolean | Resource

是否显示关闭图标,默认显示。

detents

[(SheetSize | Length), ( SheetSize | Length)?, (SheetSize | Length)?]

半模态页面的切换高度档位。

说明:

底部弹窗竖屏生效,元组中第一个高度为初始高度。

。。。。剩余属性参考文档

看文档真是累死了,所以让我们打代码吧!

来个实践:

  • 效果 1:弹出半模态,高度固定
  • 效果 2:弹出半模态,通过控制条切换高度档位

基础代码:

@Entry
@Component
struct Page02_bindSheetOptions {
  // isShow1 和 isShow2 分别控制不同的半模态
  @State isShow1: boolean = false
  @State isShow2: boolean = false

  build() {
    Column({ space: 20 }) {
      Text('半模态转场-常用属性' + this.isShow1)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      Button('显示半模态1-高度固定')// 3. 绑定半模态 bindSheet
        .bindSheet($$this.isShow1, this.sheetBuilder1())
        .onClick(() => {
          // 4. 修改状态变量,控制显示
          this.isShow1 = true
        })

      Button('显示半模态 2-切换高度档位')
        .bindSheet($$this.isShow2, this.sheetBuilder2())
        .onClick(() => {
          this.isShow2 = true
        })

    }
    .width('100%')
    .height('100%')
    .padding(20)
  }

  @Builder
  sheetBuilder1() {
    Column() {
      Text('半模态 1')
        .fontSize(40)
    }
    .backgroundColor(Color.Pink)
    .width('100%')
    .height('100%')
  }

  @Builder
  sheetBuilder2() {
    Column() {
      Text('半模态 2')
        .fontSize(40)
    }
    .backgroundColor(Color.Orange)
    .width('100%')
    .height('100%')
  }
}

接下来给你们一点时间......300,299,298...0!时间到,揭晓答案!

@Entry
@Component
struct Page02_bindSheetOptions {
  // isShow1 和 isShow2 分别控制不同的半模态
  @State isShow1: boolean = false
  @State isShow2: boolean = false

  build() {
    Column({ space: 20 }) {
      Text('半模态转场-常用属性' + this.isShow1)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      Button('显示半模态1-高度固定')// 3. 绑定半模态 bindSheet
        .bindSheet($$this.isShow1, this.sheetBuilder1(), {
          // height: SheetSize.MEDIUM// 枚举的方式设置
          height: 100// 设置具体的值
        })
        .onClick(() => {
          // 4. 修改状态变量,控制显示
          this.isShow1 = true
        })

      Button('显示半模态 2-切换高度档位')
        .bindSheet($$this.isShow2, this.sheetBuilder2(), {
          dragBar: true, // 是否显示控制条
          detents: [100, 200, 300] // 在多个不同的高度切换
        })
        .onClick(() => {
          this.isShow2 = true
        })

    }
    .width('100%')
    .height('100%')
    .padding(20)
  }

  @Builder
  sheetBuilder1() {
    Column() {
      Text('半模态 1')
        .fontSize(40)
    }
    .backgroundColor(Color.Pink)
    .width('100%')
    .height('100%')
  }

  @Builder
  sheetBuilder2() {
    Column() {
      Text('半模态 2')
        .fontSize(40)
    }
    .backgroundColor(Color.Orange)
    .width('100%')
    .height('100%')
  }
}

接下来我们学习全屏模块

全屏模块

名称

参数

参数描述

bindContentCover

isShow: boolean,

builder: CustomBuilder,

options?: ContentCoverOptions

给组件绑定全屏模态页面,点击后显示模态页面。模态页面内容自定义,显示方式可设置无动画过渡,上下切换过渡以及透明渐变过渡方式。

isShow: 是否显示全屏模态页面。

从API version 10开始,该参数支持$$双向绑定变量

builder: 配置全屏模态页面内容。

options: 配置全屏模态页面的可选属性(详细可以参考文档,用的不多)

核心步骤:

  1. 定义状态变量,boolean
  2. 通过 Builder 定义结构
  3. 绑定全屏模态 bindContentCover
  4. 修改状态变量,控制显示

来一个简单实现开开胃

@Entry
@Component
struct Page05_bindContentCover {
  // 1. 定义状态变量,boolean
  @State isShow: boolean = false

  // 2.通过 Builder 定义结构
  @Builder
  myBuilder() {
    Column() {
      Button('关闭')
        .onClick(() => {
          this.isShow = false
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#0094ff')
    .justifyContent(FlexAlign.Center)
  }

  build() {
    Column() {
      Button(`显示全屏模态${this.isShow}`)
        .fontSize(20)
        .margin(10)// 绑定全屏模态 bindContentCover
        .bindContentCover(this.isShow, this.myBuilder())
        .onClick(() => {
          // 修改状态变量,控制显示
          this.isShow = true
        })
    }
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .height('100%')
  }
}

非常有趣,今天我们就学习到这里,喜欢的可以点点关注!!这里是鸿蒙开天组,我们下一篇文章不见不散!

以上内容仅供学习交流,如有违法或者侵权可以联系删除。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐