微信小程序> 微信小程序仿微信聊天语音播放自定义控件

微信小程序仿微信聊天语音播放自定义控件

浏览量:803 时间: 来源:吃得太多

效果如↓↓↓        假装有声音。

很郁闷,没有做到完全解耦,试了试音频播放组件<audio></audio>与API wx.createInnerAudioContext()在自定义控件中没有作用!

也就是说,不能只传一个语音的url给自定义的控件了!播放的控制还得放在页面中,控制播放、暂停、等标识数据都得传,说是自定义控件,其实也就是一个UI罢了,与安卓IOS的继承再封装没法比,与小程序中引用片段<template name="×××"></template> 相比 还没有人家简单。

个人认为:小程序的自定义组件是没有灵魂的,与引用片段无本质区别,当然,这是我乱说的,欢迎大神指导...

然后上代码吧:希望能抛砖引玉

1.在合适的目录右键新建component 自定义控件voice-view

wxml:

<!-- 仿微信语音播放 --><view class='voices'>  <view class='voice' hover-class='voice-hover' bindtap='playVoice' data-index='{{index}}' style="width:{{100+220*length/10}}rpx">    <image src="../images/{{playing?'stop':'play'}}.png" style='margin-left:22rpx;' ></image>    <image src='../images/voice{{voiceImg}}.png' style='margin-right:10rpx;'></image>  </view>  <text style='font-size:24rpx;font-weight:400;color:rgba(155,155,155,1);line-height:34rpx;margin-left:16rpx'>{{length}}s</text></view>

wxss:

/* components/voice-view.wxss */.voices {  padding: 10rpx 0;  display: flex;  flex-direction: row;  align-items: center;}.voices .voice {  width: 320rpx;  height: 40rpx;  background: rgba(35, 69, 156, 1);  border-radius: 20rpx;  display: flex;  flex-direction: row;  align-items: center;  justify-content: space-between;}.voices .voice-hover{  background: rgb(28, 54, 121);}.voices .voice image {  width: 26rpx;  height:26rpx;}

js:

// components/voice-view.jsComponent({  /**   * 组件的属性列表   */  properties: {    index: {      type: Number,      value: 0    },    length: {      type: Number,      value: 10,    },    url: {      type: String,      value: ''    },    playing: {      type: Boolean,      value: false,      observer: "playAnima" // observer 表示属性值被更改时的响应函数    }  },  /**   * 组件的初始数据   */  data: {    voiceImg: 3,  },  /**   * 组件的方法列表   */  methods: {    //伪动画播放方法    playAnima: function() {      var that = this      if (!that.data.playing) {        this.setData({          voiceImg: 3        })      } else {        switch (that.data.voiceImg) {          case 1:            that.setData({              voiceImg: 2            })            break          case 2:            that.setData({              voiceImg: 3            })            break          case 3:            that.setData({              voiceImg: 1            })            break        }        setTimeout(function() {          that.playAnima()        }, 500)      }    },    //播放、暂停音频    playVoice: function(e) {      this.triggerEvent('voiceClickss', {        index: this.data.index,        url:this.data.url,        playing:this.data.playing      });    },  },})

2.page引用:要引用的先加声明:page页面的json中:

{  "usingComponents": {    "voice-view":"../../components/voice-view"  },  "navigationBarTitleText": "test"}

 布局wxml:

注意:url、length、等都是自定义控件中properties的属性。

<!--pages/test/test.wxml--><view wx:for="{{list}}">  <voice-view url="{{item.url}}" length="{{item.length}}" playing="{{item.playing}}" index="{{index}}" bind:voiceClickss='voiceClick' /></view>

bind:voiceClickss='voiceClick'  的意思是:绑定自定义控件中“voiceClickss”方法至page页面中“voiceClick”方法

当点击自定义控件时,执行控件中:
    playVoice: function(e) {
      this.triggerEvent('voiceClickss', {
        index: this.data.index,
        url:this.data.url,
        playing:this.data.playing
      });
    },

将执行page页面中方法,并传值index...

js:

// pages/test/test.jsvar playingSrc = ''var playingIndex = 0const innerAudioContext = wx.createInnerAudioContext()Page({  data: {    list: [{      url: 'https://fanyi.baidu.com/gettts?lan=en&text=%20pop%2Fdance%2Fclassical%2Fchurch%20music%20&spd=3&source=web',        length: 3,        playing: false      },      {        url: 'https://fanyi.baidu.com/gettts?lan=en&text=She%20could%20hear%20music%20playing%20somewhere.&spd=3&source=web',        length: 4,        playing: false      },      {        url: 'https://fanyi.baidu.com/gettts?lan=en&text=the%20popularity%20of%20Mozart%27s%20music&spd=3&source=web',        length: 8,        playing: false      },    ],  },  //播放、暂停音频  voiceClick: function(e) {    console.log('page,-----voiceClick',)    var index = e.detail.index    playingIndex = index    var playing = e.detail.playing    var src = this.data.list[index].url    console.log('播放url', src)    if (playingSrc != src) {      innerAudioContext.stop()      innerAudioContext.src = src      playingSrc = src      innerAudioContext.play()    } else if (!playing) {      console.log('暂停中---->播放')      innerAudioContext.play()    } else {      console.log('播放中---->暂停')      innerAudioContext.pause()    }  },  /**   * 生命周期函数--监听页面加载   */  onLoad: function(options) {    var that = this    innerAudioContext.autoplay = false    innerAudioContext.obeyMuteSwitch = false    innerAudioContext.onPlay(function() {      that.setStatus(true)    })    innerAudioContext.onPause(function() {      that.setStatus()    })    innerAudioContext.onStop(function() {      that.setStatus()    })    innerAudioContext.onEnded(function() {      that.setStatus()    })    innerAudioContext.onError(function(res) {      that.setStatus()      var t = '未知错误'      switch (res.errCode) {        case 10001:          t = '系统错误'          break;        case 10002:          t = '网络错误'          break;        case 10003:          t = '文件错误'          break;        case 10004:          t = '格式错误'          break;      }      wx.showToast({        title: t,        icon: 'none'      })    })  },  setStatus: function(sta = false) {    for (var i = 0; i < this.data.list.length; i++) {      this.data.list[i].playing = false    }    if (sta)      this.data.list[playingIndex].playing = true    this.setData({      list: this.data.list    })  }})

开发中发现微信自带的判断音频播放是否暂停状态的方法不好用!无奈只好另写了个变量播放状态playing 

wx文档: boolean paused  当前是是否暂停或停止状态(只读)

哦,顺便把图片资源文件给大家:

小程序
voice3.png
小程序
voice2.png
小程序
voice1.png
​​​​​​
小程序
stop.png
 
小程序
play.png
 
微信小程序

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎