鸿蒙 next 实战: 电子木鱼实现 | f2e 前端技术论坛-大发黄金版app下载
正所谓:hello word 是程序员学任何一门语言的第一个程序实践。这其实也是一个不错的正反馈,那如何让学习鸿蒙 next 更有成就感呢?下面就演示一下从零开发一个鸿蒙 next 版的电子木鱼,主打就是一个抽象!
- 页面布局
- 木鱼点击
- 木鱼音效
- 动画特效
- 自定义弹窗
页面布局
arkts 定义了声明式 ui 描述、自定义组件和动态扩展 ui 元素的能力,配合 arkui 开发框架中的系统组件及其相关的事件方法、属性方法等共同构成 ui 开发的主体。我们下面要完成的主要是一个木鱼和设置按钮、自动按钮。
build() {
column() {
hdnav({ title: '电子木鱼', showrighticon: false, iconcolor: $r('app.color.white'), titlecolor: '#ffffff' })
row() {
text(this.woodentype[this.type] ':' this.score).fontsize(22).fontcolor("#ffffff").width('100%').textalign(textalign.center)
}.width("100%").height("8%")
row() {
image($r('app.media.setting')).width(25).height(25).margin(16).onclick(() => {
if (this.dialogcontroller != null) {
this.dialogcontroller.open()
}
})
}.width('100%')
row() {
image($r('app.media.foreground')).width(40).height(40).margin({left:8,top:5})
}.width('100%')
.onclick(() => {
this.handlepopup = !this.handlepopup
})
.bindpopup(this.handlepopup, {
message: '数据统计功能,正在完善中~',
})
row() {
if (this.ispresent) {
text(this.woodentype[this.type] ': ' this.woodenfishnum).fontsize(16).fontcolor("#ffffff").width('100%').textalign(textalign.center)
.transition(this.effect)
}
}.width('100%').height('25%')
.alignitems(verticalalign.top)
row() {
image($r('app.media.muyu'))
.width(this.iszoomed == true ? this.targetwidth * 1.2 : this.targetwidth * 1)
.height(this.iszoomed == true ? this.targetheight * 1.2 : this.targetheight * 1)
}
.width('100%')
.height('25%')
.alignitems(verticalalign.center)
.justifycontent(flexalign.center)
row() {
toggle({ type: toggletype.switch })
.onchange((ison: boolean) => {
if(ison) {
promptaction.showtoast({ message: 'auto is on.' })
} else {
promptaction.showtoast({ message: 'auto is off.' })
}
})
text('自动' this.woodentype[this.type]).fontsize(18).fontcolor('#ffffff').height(40).margin({left: 10})
}.width('100%').height('10%').justifycontent(flexalign.center)
}
.height("100%")
.backgroundcolor('rgba(0, 0, 0, 1.00)')
}
木鱼点击
木鱼是一张图片,也就是给该图绑定一个点击事件,点击一次有三个动作需要执行:
- 木鱼有放大的效果
- 有类似功德文字的飘动
- 功德数值的累加
而点击的时候要看到实时的效果,所以可以声明三个状态,通过 state 的修改,从而驱动 ui 更新,以下的 animateto 是给域名的放大添加的一个平滑效果。
// 积分
@state score: number = 0
// 积分文字
@state ispresent: boolean = false
// 木鱼是否放大
@state iszoomed: boolean = false
// 木鱼ui
image($r('app.media.muyu'))
.width(this.iszoomed == true ? this.targetwidth * 1.2 : this.targetwidth * 1)
.height(this.iszoomed == true ? this.targetheight * 1.2 : this.targetheight * 1)
.onclick((event) => {
animateto({ curve: curves.springmotion() }, () => {
this.iszoomed = !this.iszoomed;
if (this.iszoomed == true) {
this.ispresent = true;
this.score = this.woodenfishnum;
this.onclickplay();
}
})
// 定时缩小/定时文字消失
settimeout(() => {this.iszoomed = false;}, 50);
settimeout(() => {this.ispresent = false}, 600);
})
木鱼音效
木鱼音效是点击时的咚咚的声音,这里就要使用到 harmonyos next 的音频服务。这里需要注意一点,项目运行预览无法播放,一定要模拟器或真机才可以调试音频的播放效果。
// 销毁音效工具
onclickdestroy= ()=>{
audiomgr.ins().destroy();
console.log('audio', 'destroy');
}
// 初始化音效工具
onclickinit = ()=>{
audiomgr.ins().init();
console.log('audio', 'init');
}
// 播放指定音效
onclickplay = ()=>{
audiomgr.ins().play();
console.log('audio', 'playing');
}
动画特效
这里的动画效果主要是点击木鱼,从下网上飘出一个文字然后消失的特效。在鸿蒙中可以通过 transitioneffect 方法添加效果,首先创建特效,然后再文字上挂载。
// 上移入场特效
private effect: object =
transitioneffect.opacity
// 初始正常大小// 假设动画持续时间为500ms
.combine(transitioneffect.scale({ x: 1, y: 1 }).animation({ curve: curves.springmotion(0.6, 1.2), duration: 0 }))
// 向上平移150单位// 与上一步同时开始
.combine(transitioneffect.translate({ x: 0, y: 400 }).animation({ curve: curves.springmotion(0.6, 1.2), duration: 10000, delay: 50 }))
// 淡出至完全透明// 在平移结束后开始淡出
.combine(transitioneffect.opacity(0).animation({ curve: curves.springmotion(0.6, 1.2), duration: 1000, delay: 0 }));
自定义弹窗
经过前面布局,事件绑定,音效播放,一个简单的电子木鱼其实已经完成了。但是为了增添趣味和后期扩展,这里再加一个设置功能,通过按钮打开配置项弹窗,设置包括:
- 类型选项 (功德、财运、桃花运等)
- 音效选项 (各种解压的音效素材)
- 皮肤管理 (木鱼的 ui 界面设置)
- 数值修改 (对展示的累加数值做任意修改)
- 其他 (是否关闭音效,是否自动点击等)
// 弹窗层(ui开发-组件-自定义弹窗)
@customdialog
struct settingdialog {
controller?: customdialogcontroller
// 父子组件双向同步,文档见 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-v5/arkts-link-v5
@link woodenfishtype: number
// 木鱼敲击的数值
@link woodenfishnum: number
build() {
column() {
row() {
text('愿望:').fontsize(17).fontweight(600)
radio({ value: '功德', group: 'word' }).checked(true).onchange((ischecked: boolean) => {
if(ischecked) {
this.woodenfishtype = 0
}
})
text('功德').fontsize(15)
radio({ value: '财富', group: 'word' }).onchange((ischecked: boolean) => {
if(ischecked) {
this.woodenfishtype = 1
}
})
text('财富').fontsize(15)
radio({ value: '桃花运', group: 'word' }).onchange((ischecked: boolean) => {
if(ischecked) {
this.woodenfishtype = 2
}
})
text('桃花运').fontsize(15)
}
.width('100%')
.margin({bottom: 12})
.justifycontent(flexalign.start)
row() {
text('数值:').fontsize(16).fontweight(600)
textinput({text:'1'}).type(inputtype.number).width(180).onchange((value: string) => {
this.woodenfishnum = parseint(value)
})
}
.width('100%')
.margin({bottom: 12})
.justifycontent(flexalign.start)
row() {
text('音效:').fontsize(16).fontweight(600)
toggle({ type: toggletype.switch })
}
.width('100%')
.margin({bottom: 12})
.justifycontent(flexalign.start)
row() {
text('皮肤:').fontsize(16).fontweight(600)
radio({ value: '默认', group: 'skin' }).checked(true)
text('木鱼').fontsize(15)
radio({ value: '悟空', group: 'skin' })
text('黑悟空').fontsize(15)
radio({ value: '典韦', group: 'skin' })
text('典韦').fontsize(15)
}
.width('100%')
.margin({bottom: 12})
.justifycontent(flexalign.start)
}.padding({top: 28, left: 15})
}
}
这里需要注意的是:父子组件的数据传递。因为自定义弹窗和木鱼是两个不同的组件,而点击弹窗中的比如类型切换或修改的数值,全部要更新到木鱼组件的展示当中。
当然鸿蒙也提供了 @link 装饰器,用于与其父组件中的数据源共享相同的值,可以结合上面代码和下方截图参考其用法。
到这里,一个通用型的鸿蒙 next 版电子木鱼就完成了。不管是组件交互还是布局都还好,唯一让我觉得不适应的是动画特效。
如果用这种方式实现电子烟花肯定不行,所以下次将换一种方法快速实现烟花秀,以及页面间的跳转,待更新~
本作品采用《cc 协议》,转载必须注明作者和本文链接