鸿蒙带你实现丝滑的弹框
一、模态框应用场景。
在生活当中,我们无时无刻不在接触着拥有弹窗效果的APP,在使用的过程中,我们发现它的存在,给我们带来了很大的便利,比如:
- 我们在选择地址的时候需要用户进行多步操作或选择时,通过全模态转场弹出一个新的简洁的页面,来让用户便捷的进行选择地址的操作。
- 用户需要分享或显示菜单的时候。
效果图
二、模态转场的特点。
模态转场是一种在用户界面设计中常用的动画效果,特点是在旧的界面上覆盖一个新的页面,给用户流畅的体验,使页面切换更加自然和流畅。
- 不消失性:新的界面直接覆盖在旧的界面上,不会使旧的页面消失。
- 动画效果:通过添加过渡动画、如渐变、滑动、缩放等,使新界面出现和旧界面的隐藏更加平滑和吸引人。
三、实现(全/半)模态转场的思路与技术。
1.实现思路
- 定义模态展示界面:使用适合的布局和组件构建页面,要确保内容清晰和布局合理。
- 设置转场动画:通过给新界面添加新旧界面的隐藏和出现添加过渡效果,实现丝滑的转场,如平移、缩放、淡入淡出。
- 控制显示和隐藏:通过状态变量控制模态界面的显示和隐藏,以及在适当的时机和位置触发转场动画。
2.使用的技术
在鸿蒙开发中,半模态转场通过bindSheet属性实现、全模态转场通过bindContentCover属性实现,两者转场是类似的,都需要开发者定义一个控制变量来控制全/半模态对话框的显示和隐藏,并通过bindSheet/bindContentCover将控制变量与模态对话框的内容进行绑定。此外,bindSheet/bindContentCover还允许开发者自定义转场动画、背景色等属性,以提供更加丰富的用户体验。
3.语法及参数的使用
语法
@Entry
@Component
struct SheetTransitionExample1 {
// 1. 定义控制变量
@State isShow: boolean = false
// 2.自定义内容
@Builder
myBuilder() {
// 结构略
}
build() {
Column() {
Button(`显示半/全模态`)
// 3.绑定半模态框
.bindSheet(this.isShow, this.myBuilder()) //半模态框绑定,这里需要传入两个参数,一个是控制变量,一个是自定义内容
//.bindContentCover(this.isShow, this.myBuilder()) //全模态框绑定,这里需要传入两个参数,一个是控制变量,一个是自定义内容
.onClick(() => {
// 4.控制显示
this.isShow = true
})
}
}
}
参数
参数 | 参数描述 |
---|---|
isShow | 是否显示半模态页面。 |
builder: | 配置半模态页面内容。 |
options?: | 配置半模态页面的可选属性。 |
可选属性sheetOptions
名称 | 类型 | 必填 | 描述 |
---|---|---|---|
height | SheetSize、Length | 否 | 半模态高度,默认是LARGE。说明:底部弹窗竖屏时,当设置detents时,该属性设置无效。 |
dragBar | boolean | 否 | 是否显示控制条,默认显示。说明:半模态面板的dentents属性设置多个不同高度并且设置生效时,默认显示控制条。否则不显示控制条。 |
showClose | boolean 、 Resource | 否 | 是否显示关闭图标,默认显示。 |
detents | 否 | 半模态页面的切换高度档位。**说明:**底部弹窗竖屏生效,元组中第一个高度为初始高度。 |
4.注意
在非双向绑定情况下,以拖拽方式关闭半模态页面不会改变isShow参数的值。 为了使isShow参数值与半模态界面的状态同步,建议使用 $$ (建议最后加)双向绑定isShow参数。
5.实现效果图及代码(分享给好友)
代码
/*
* 需求:
* 1. 点击按钮 弹出半模态
* 定义状态变量
* bindSheet($$this.状态变量,自定义的 Builder,{})
* */
@Entry
@Component
struct SheetTransitionExample1 {
@State isShow:boolean = false
// 半模态 Builder
@Builder
myBuilder() {
Column() {
Stack({ alignContent: Alignment.End }) {
Text('分享给好友')
.width('100%')
.textAlign(TextAlign.Center)
.fontSize(20)
// 自己的关闭按钮-因为没用默认的,需要自己实现关闭逻辑
Image($r('app.media.ic_public_cancel'))
.width(25)
.fillColor('#c0c0c0')
.onClick(()=>{
this.isShow=false
})
}
.width('100%')
Row() {
this.itemBuilder($r('app.media.ic_share_sina'), '微信')
this.itemBuilder($r('app.media.ic_share_url'), '朋友圈')
this.itemBuilder($r('app.media.ic_share_wechat'), '微博')
this.itemBuilder($r('app.media.ic_share_pyq'), '复制链接')
}
.height(80)
.width('100%')
.margin({ top: 30 })
.justifyContent(FlexAlign.SpaceAround)
}
.padding(15)
}
// 半模态 内部图片 Builder
@Builder
itemBuilder(src: ResourceStr, title: string) {
Column() {
Image(src)
.width(50)
Text(title)
.fontSize(14)
.margin({ top: 10 })
}
}
build() {
Column() {
Button(`显示半模态`)
.fontSize(20)
.bindSheet($$this.isShow,this.myBuilder(),{
height:SheetSize.FIT_CONTENT,
showClose:false // 默认的关闭按钮 有背景,不太好看 关掉
})
.onClick(()=>{
this.isShow=true
})
// 展示半模态Builder
// this.myBuilder()
}
.justifyContent(FlexAlign.Center)
.width('100%')
.height('100%')
}
}
注意:
- 半模态中的图片如果不设置高度,默认不会加载,导致半模态默认不显示图片
- 解决方法:给图片或图片的容器加个高度即可