鸿蒙 next 实战: 电子木鱼实现 | f2e 前端技术论坛-江南app体育官方入口

正所谓:hello word 是程序员学任何一门语言的第一个程序实践。这其实也是一个不错的正反馈,那如何让学习鸿蒙 next 更有成就感呢?下面就演示一下从零开发一个鸿蒙 next 版的电子木鱼,主打就是一个抽象!

92210410404e8ff27918f02e3d85cf17_up-0e821fc204618a9429123f0a852e11df614.png

  1. 页面布局
  2. 木鱼点击
  3. 木鱼音效
  4. 动画特效
  5. 自定义弹窗

39c305f85ef328c3890d44df61de3f9e_up-2bbe0ef0a0f3df2842362470e5921f57641.jpg

页面布局

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 的音频服务。这里需要注意一点,项目运行预览无法播放,一定要模拟器或真机才可以调试音频的播放效果。

a50716261bdfd14746bf196b89a808b9_up-957f2f2082d91c8fd3f7bdcd25ac19a7577.png

// 销毁音效工具
  onclickdestroy= ()=>{
    audiomgr.ins().destroy();
    console.log('audio', 'destroy');
  }
  // 初始化音效工具
  onclickinit = ()=>{
    audiomgr.ins().init();
    console.log('audio', 'init');
  }
  // 播放指定音效
  onclickplay = ()=>{
    audiomgr.ins().play();
    console.log('audio', 'playing');
  }

e095d6c6c7fd61ee09ad2e6750147361_up-bb7dc3e97e316f453c7f6a72aec07052dae.png

动画特效

这里的动画效果主要是点击木鱼,从下网上飘出一个文字然后消失的特效。在鸿蒙中可以通过 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 }));

a38c10c34fdb93be33ba7ca5f1e4bd61_up-dbe42f5c89bf43d36dcc62ab8459986682a.png

自定义弹窗

经过前面布局,事件绑定,音效播放,一个简单的电子木鱼其实已经完成了。但是为了增添趣味和后期扩展,这里再加一个设置功能,通过按钮打开配置项弹窗,设置包括:

  • 类型选项 (功德、财运、桃花运等)
  • 音效选项 (各种解压的音效素材)
  • 皮肤管理 (木鱼的 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 装饰器,用于与其父组件中的数据源共享相同的值,可以结合上面代码和下方截图参考其用法。

682dc27d391be1c5be1c3f2f088dc353_up-c59691bbee82b725b86786632bf238bb60e.png

到这里,一个通用型的鸿蒙 next 版电子木鱼就完成了。不管是组件交互还是布局都还好,唯一让我觉得不适应的是动画特效。
如果用这种方式实现电子烟花肯定不行,所以下次将换一种方法快速实现烟花秀,以及页面间的跳转,待更新~

本作品采用《cc 协议》,转载必须注明作者和本文链接
公众号: zero开发, 专注后端实战技术分享,致力于给猿友们提供有价值的内容。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
网站地图