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

xiaoxiao2021-03-01  52

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

很郁闷,没有做到完全解耦,试了试音频播放组件<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.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的属性。

<!--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.js var playingSrc = '' var playingIndex = 0 const innerAudioContext = wx.createInnerAudioContext() Page({ data: { list: [{ url: 'https://fanyi.baidu.com/gettts?lan=en&text= pop/dance/classical/church music &spd=3&source=web', length: 3, playing: false }, { url: 'https://fanyi.baidu.com/gettts?lan=en&text=She could hear music playing somewhere.&spd=3&source=web', length: 4, playing: false }, { url: 'https://fanyi.baidu.com/gettts?lan=en&text=the popularity of Mozart's music&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  
转载请注明原文地址: https://www.6miu.com/read-4549914.html

最新回复(0)