1.气泡提示(Popup)
Popup属性可绑定在组件上显示气泡弹窗提示,设置弹窗内容、交互逻辑和显示状态。
气泡分为两种类型:一种是系统提供的气泡PopupOptions,一种是自定义的气泡CustomPopupOptions。
● 其中PopupOptions为系统提供的气泡,通过配置primaryButton、secondaryButton来设置带按钮的气泡。
● CustomPopupOptions通过配置builder参数来设置自定义的气泡。
1.1 文本提示气泡
文本提示气泡常用于只展示带有文本的信息提示,不带有任何交互的场景。
@Entry
@Component
struct PopupExample {
@State handlePopup: boolean = false
build() {
Column() {
Button('显示气泡')
.bindPopup(this.handlePopup, {
message: '这是气泡的内容',
onStateChange: (e) => { //气泡发生改变时调用
if (!e.isVisible) {
this.handlePopup = false
}
}
})
.onClick(() => {
this.handlePopup = !this.handlePopup
})
}.width('100%').padding({ top: 5 })
}
}
1.2 带按钮的气泡
通过primaryButton、secondaryButton属性为气泡最多设置两个Button按钮,通过此按钮进行简单的交互,开发者可以通过配置action参数来设置想要触发的操作。
@Entry
@Component
struct PopupExample22 {
@State handlePopup: boolean = false
build() {
Column() {
Button('PopupOptions').margin({ top: 200 })
.onClick(() => {
this.handlePopup = !this.handlePopup
})
.bindPopup(this.handlePopup, {
message: 'This is a popup with PopupOptions',
primaryButton: {
value: 'Confirm',
action: () => {
this.handlePopup = !this.handlePopup
console.info('confirm Button click')
}
},
secondaryButton: {
value: 'Cancel',
action: () => {
this.handlePopup = !this.handlePopup
}
},
onStateChange: (e) => {
if (!e.isVisible) {
this.handlePopup = false
}
}
})
}.width('100%').padding({ top: 5 })
}
}
1.3 自定义气泡
手机上点击应用图标时会弹出一个气泡,可以进行分享、卸载等操作。我们现在也可以做一个类似的效果出来,长按图片弹出气泡。如下图所示
- 在Index中用@Builder构建气泡的内容。
@Entry
@Component
struct Index{
//1.自定义气泡内容
@Builder
InfoPopup() {
Column({ space: 10 }) {
Row({ space: 20 }) {
SymbolGlyph($r('sys.symbol.info_circle')).fontWeight(FontWeight.Medium)
Text('应用信息').fontSize(12).fontWeight(FontWeight.Normal)
}
Row({ space: 20 }) {
SymbolGlyph($r('sys.symbol.share')).fontWeight(FontWeight.Medium)
Text('分享').fontSize(12).fontWeight(FontWeight.Normal)
}
Row({ space: 20 }) {
SymbolGlyph($r('sys.symbol.trash')).fontWeight(FontWeight.Medium)
Text('卸载').fontSize(12).fontWeight(FontWeight.Normal)
}
}
.width(150)
.height(100)
.padding(5)
.alignItems(HorizontalAlign.Start)
.padding({ left: 10, top: 20 })
}
//2.构建页面的函数
build(){
...
}
}
- 在Index的build函数中,使用Image放置一张图片,长按图片弹出自定义气泡。
@Entry
@Component
struct Index{
//1.自定义气泡内容
...
//2.构建页面的函数
handlePopup: boolean =false
build(){
Column() {
Image($r('app.media.huawei_watch'))
.width(100)
.width(100)
.margin({ top: 200 })
.draggable(false) //Image是默认是可拖拽控件,与长按手势有冲突,所以必须禁止拖拽。
.gesture(LongPressGesture({duration: 500 }) //添加长按手势
.onAction((event: GestureEvent) => {
this.handlePopup = !this.handlePopup
}))
.bindPopup(this.handlePopup, { //给图片绑定气泡
builder: this.InfoPopup(),
onStateChange: (e) => {
if (!e.isVisible) {
this.handlePopup = false
}
}
})
}.width('100%').padding({ top: 5 })
}
}
手势是一个通用事件,任何组件都可以绑定手势事件
● 通过.gesture(手势类型)给组件绑定手势识别
● LongPressGesture 用于触发长按手势事件,触发长按手势的最少手指数为1,最短长按时间为500毫秒。
Button('长按')
.gesture(
LongPressGesture({
fingers:1, //长按最少得手指个数
repeat: true, //是否重复触发手势回调,默认为false
duration: 1000, //长按触发时间,1000毫秒
})
.onAction((event:GestureEvent)=>{
//长按完成触发
console.log('长按触发')
})
.onActionEnd((event:GestureEvent)=>{
//长按完成,手指抬起后触发回调。
console.log('长按释放')
})
)
2.菜单(Menu)
Menu是菜单接口,一般用于鼠标右键弹窗、点击弹窗等。
2.1 默认菜单
如果下图所示,点击按钮时就可以弹出一个菜单,有3个菜单项,每一个菜单项用MenuElement表示。
代码如下,给按钮绑定菜单,调用bindMenu(content: Array)属性。
Entry
@Component
struct Index {
build() {
Column() {
Button('click for Menu')
.bindMenu([
//第一个菜单项
{
value: 'Menu1',
action: () => {
console.warn('handle Menu1 select')
}
},
//第二个菜单项
{
value: 'Menu2',
action: () => {
console.warn('handle Menu1 select')
}
},
//第三个菜单项
{
value: 'Menu3',
action: () => {
console.warn('handle Menu1 select')
}
}
])
}.width('100%').padding({ top: 5 })
}
}
2.2 自定义菜单
当默认样式不满足开发需求时,可使用@Builder自定义菜单内容。通过bindMenu接口进行菜单的自定义。
如:我们想要实现下面的菜单样式,而且二级菜单,此时就只能用自定义菜单了。
● 菜单是一个容器,整个菜单用Enum表示
● 每一个菜单项用EnumItem表示,每一个菜单项由三个部分组成(图片,文字,图片)
● 可以把多个菜单项归为一组,用MenuItemGrop(‘分组标题’)
根据上面分析把菜单内容构建出来,使用@Builder装饰。
@Entry
@Component
struct Index {
//1.一级菜单
@Builder
MyMenu() {
Menu() {
MenuItem({ startIcon: $r('app.media.startIcon'), content: '菜单选项1' })
MenuItem({ startIcon: $r('app.media.startIcon'), content: '菜单选项2' }).enabled(false)
MenuItem({
startIcon: $r('sys.media.ohos_ic_public_share'),
content: '菜单选项3',
endIcon: $r('sys.media.ohos_ic_public_arrow_right'),
builder: this.SubMenu()
})
MenuItemGroup({ header: '小标题' }) {
MenuItem({ startIcon: $r('sys.symbol.list_checkmask'), content: '菜单选项4' })
.selectIcon(true)//显示选中图标,在选项前打一个✅
.selected(true)//是否选中
.onChange((selected) => {
console.info("menuItem select:" + selected) //选中
})
MenuItem({
startIcon: $r('sys.media.ohos_ic_public_text'),
content: '菜单选项5',
endIcon: $r('sys.media.ohos_ic_public_arrow_right')
})
}
MenuItem({
startIcon: $r('sys.media.ohos_ic_public_voice_off'),
content: '菜单选项6',
endIcon: $r('sys.media.ohos_ic_public_arrow_right')
})
}.width(200)
}
//2.二级菜单
@Builder
SubMenu() {
Menu() {
MenuItem({ content: "复制", labelInfo: "Ctrl+C" })
MenuItem({ content: "粘贴", labelInfo: "Ctrl+V" })
}
}
//3.将一级菜单绑定到按钮上
build() {
Column() {
Button('菜单').bindMenu(this.MyMenu())
}.width('100%').alignItems(HorizontalAlign.Center).margin({ top: 20 })
}
}