#跟着晓明学鸿蒙# RelativeContainer悬浮按钮菜单之UI实现
·
目录
- 案例介绍
- 代码实现
- 代码详解
- 1. 整体布局结构
- 2. 主按钮实现
- 3. 菜单项实现
- 4. 动画属性应用
- 5. 背景遮罩
- 总结
案例介绍
本篇文章将介绍如何实现悬浮按钮菜单的UI部分,包括主按钮、菜单项按钮和背景遮罩的布局与样式设计。
代码实现
Stack() {
// 使用RelativeContainer实现悬浮按钮菜单
RelativeContainer() {
// 主悬浮按钮
Button({
type: ButtonType.Circle,
stateEffect: true
}) {
Image(this.isExpanded ? $r('app.media.close_icon') : $r('app.media.add_icon'))
.width(24)
.height(24)
.rotate(this.isExpanded ? 45 : 0)
.animation({
duration: 300,
curve: Curve.Ease
})
}
.width(60)
.height(60)
.backgroundColor('#3478F6')
.id('main_button')
.alignRules({
center: { anchor: '__container__', align: HorizontalAlign.Center },
middle: { anchor: '__container__', align: VerticalAlign.Center }
})
.onClick(() => this.toggleMenu())
.zIndex(10)
// 菜单项按钮
ForEach(this.menuItems, (item, index) => {
Column() {
Button({
type: ButtonType.Circle,
stateEffect: true
}) {
Image(item.icon)
.width(24)
.height(24)
.fillColor(Color.White)
}
.width(50)
.height(50)
.backgroundColor(item.color)
Text(item.name)
.fontSize(12)
.fontColor('#666666')
.margin({ top: 4 })
.opacity(this.opacities[index])
}
.id(`menu_item_${index}`)
.alignRules({
center: { anchor: 'main_button', align: HorizontalAlign.Center },
middle: { anchor: 'main_button', align: VerticalAlign.Center }
})
.translate({
x: this.translations[index].x,
y: this.translations[index].y
})
.rotate({
x: 0,
y: 0,
z: 1,
angle: this.rotationAngles[index]
})
.scale({
x: this.scales[index],
y: this.scales[index],
z: 1
})
.opacity(this.opacities[index])
.animation({
duration: 300,
curve: Curve.Ease
})
})
}
.width('100%')
.height('100%')
// 背景遮罩层
Column()
.width('100%')
.height('100%')
.backgroundColor('#000000')
.opacity(this.isExpanded ? 0.3 : 0)
.animation({
duration: 300,
curve: Curve.Ease
})
.visibility(this.isExpanded ? Visibility.Visible : Visibility.Hidden)
.onClick(() => {
if (this.isExpanded) {
this.toggleMenu()
}
})
}
.width('100%')
.height('100%')
代码详解
1. 整体布局结构
使用Stack作为最外层容器:
- RelativeContainer实现菜单布局
- Column实现背景遮罩
- 保证遮罩在底层,按钮在上层
2. 主按钮实现
Button({
type: ButtonType.Circle,
stateEffect: true
}) {
Image(this.isExpanded ? $r('app.media.close_icon') : $r('app.media.add_icon'))
.width(24)
.height(24)
.rotate(this.isExpanded ? 45 : 0)
}
主按钮特点:
- 圆形按钮样式
- 动态切换图标
- 旋转动画效果
- 居中定位
3. 菜单项实现
ForEach(this.menuItems, (item, index) => {
Column() {
Button({
type: ButtonType.Circle,
stateEffect: true
}) {
Image(item.icon)
.width(24)
.height(24)
.fillColor(Color.White)
}
Text(item.name)
.fontSize(12)
.fontColor('#666666')
}
})
菜单项设计:
- 按钮和文本垂直排列
- 统一的按钮样式
- 动态颜色配置
- 响应式动画效果
4. 动画属性应用
.translate({
x: this.translations[index].x,
y: this.translations[index].y
})
.rotate({
x: 0,
y: 0,
z: 1,
angle: this.rotationAngles[index]
})
.scale({
x: this.scales[index],
y: this.scales[index],
z: 1
})
.opacity(this.opacities[index])
动画效果:
- translate实现位移
- rotate实现旋转
- scale实现缩放
- opacity实现透明度
5. 背景遮罩
Column()
.backgroundColor('#000000')
.opacity(this.isExpanded ? 0.3 : 0)
.visibility(this.isExpanded ? Visibility.Visible : Visibility.Hidden)
遮罩设计:
- 半透明黑色背景
- 动态显示隐藏
- 点击关闭菜单
总结
本文通过实现悬浮按钮菜单的UI部分,展示了如何构建一个具有层次感和交互性的悬浮按钮菜单。使用Stack
组件实现了主按钮和背景遮罩的层次布局,确保遮罩在底层,按钮在上层。通过RelativeContainer
灵活控制每个菜单项的位置,结合ForEach
循环动态生成菜单项按钮,并应用位移、旋转、缩放和透明度等动画属性,实现了扇形展开效果。同时,背景遮罩采用半透明黑色设计,动态显示和隐藏,并支持点击关闭菜单,提升了交互体验。整体设计注重细节,确保了视觉效果和用户体验的统一性。
更多推荐
所有评论(0)