效果图
本项目业务是几个下拉框数据是一个接口,需要根据选择的数据,实时刷新其他下拉框数据
实现方式
有4种实现方式:
- bindPopup
- 在对应的界面上盖一层组件
- promptAction.openCustomDialog
- CustomDialog:自定义弹窗
第1、2种方式都已一个共同的缺陷:如果下拉筛选框在主界面的情况(底部几个tab ,点击tab 切换界面),每个界面的顶部有下拉筛选框的情况下,下拉筛选框会遮挡不住底部的tab。
第3种方式:弹窗把状态栏无法覆盖(暂时没找到相关属性,后面找到会补充),但是也能满足现在下拉框的需求,如果是全屏覆盖显示的话 ,需要慎重考虑。
注意:第3种方式,设置 offset 偏移量 ,需要减去状态栏的高度
第3、4两种方式其实写法上差不多的。
最后还是选择第4种方式
第4种:CustomDialog实现方式
Dialog
import { RadioBean } from '../../bean/FilBean'
interface RadioInterface {
onClick?: (radioBean: RadioBean) => void
}
@Preview
@CustomDialog
export struct RadioDialog {
controller: CustomDialogController
@Prop list: RadioBean[]
click?: RadioInterface
// 单向监听:记录最后一次的选择
@Prop lastSelect: string
// 用于区分默认状态的文字,可根据此值设置字体颜色
@Prop defaultSelect: string
aboutToAppear() {
}
build() {
Column() {
Column() {
if (this.list) {
List() {
ForEach(this.list, (item: RadioBean) => {
ListItem() {
Row() {
if (this.lastSelect) {
if (this.lastSelect == item.desc) {
Text(item.desc).height('100%').fontSize(12).fontColor('#007FFF')
Image($r('app.media.icon_select_blue')).width(15).height(15)
} else {
Text(item.desc).height('100%').fontSize(12).fontColor('#303242')
}
} else {
if (item.desc == this.defaultSelect) {
Text(item.desc).height('100%').fontSize(12).fontColor('#007FFF')
Image($r('app.media.icon_select_blue')).width(15).height(15)
} else {
Text(item.desc).height('100%').fontSize(12).fontColor('#303242')
}
}
}.padding({ left: 15, right: 15 }).height(50).justifyContent(FlexAlign.SpaceBetween).width('100%')
}.onClick(() => {
if (this.click) {
this.click?.onClick!(item)
}
})
})
}
.constraintSize({ maxHeight: 400, minHeight: 0 })
.backgroundColor(Color.White)
}
}
.height('100%')
.backgroundColor("#90000000")
.onClick(() => {
this.controller.close()
})
}.height('100%').backgroundColor(Color.Transparent)
}
}
使用:
注意:
- 自定义弹窗如果封装到一个方法里,如下面代码showYearDialog所示,自定义弹窗RadioDialog内,无法使用**@Link双向绑定**,会报错
Error message:is not callable
- 不放在单独方法里,@Link双向绑定,是可以正常使用的
showYearDialog() {
this.controller = new CustomDialogController({
builder: RadioDialog({
lastSelect: this.year,
defaultSelect: '全部年份',
list: this.filBean.yearList,
click: {
onClick: (item) => {
//点击选项后 处理自己的交互效果
if (item.desc) {
if (item.desc == '全部年份') {
this.year = ''
} else {
this.year = item.desc
}
this.tabArr[2] = item.desc
this.pageIndex = 1
this.reqSearch()
}
this.controller?.close()
}
}
}),
cancel: () => {
this.controller?.close()
},
// 设置全屏弹窗,利用offset设置偏移量
// this.postionY(刚好贴着组件下方弹窗) = 当前组件的高度 + 组件顶部在屏幕中距离顶部的距离
offset: { dx: 0, dy: this.postionY },
autoCancel: true,
customStyle: true,
maskColor: Color.Transparent,
openAnimation: { duration: 0 },
closeAnimation: { duration: 0 }
});
this.controller.open()
}
this.postionY
点击组件可根据 ClickEvent 获取具体组件在屏幕中的位置