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

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

微信小程序仿微信聊天语音播放自定义控件_第1张图片

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

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

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

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

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

wxml:



  
    
    
  
  {{length}}s

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.js
Component({
  /**
   * 组件的属性列表
   */
  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的属性。



  

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.js
var playingSrc = ''
var playingIndex = 0
const 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
 

你可能感兴趣的:(微信小程序,微信小程序开发踩坑)