实现音乐列表循环或者单曲循环

实现音乐列表循环或者单曲循环,第1张

概述无论是单曲循环还是列表循环都要先有一个音乐列表,在这里我使用了Recyclerview,并且自定义了适配器<androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/musicslist"android:layout_width="355dp"android:layout_height="match_parent"android:layout_gra

无论是单曲循环还是列表循环都要先有一个音乐列表,在这里我使用了RecyclervIEw,并且自定义了适配器

<androIDx.recyclervIEw.Widget.RecyclerVIEw
androID:ID="@+ID/musicsList"
androID:layout_wIDth="355dp"
androID:layout_height="match_parent"
androID:layout_gravity="center_horizontal"
androID:layout_margintop="15dp"/>
以上是布局文件
每一个item的形式也要创建一个layout布局:
<linearLayout
xmlns:androID="http://schemas.androID.com/apk/res/androID"
androID:layout_wIDth="355dp"
androID:layout_height="82dp"
androID:orIEntation="vertical"
androID:layout_gravity="center_horizontal">
<androIDx.coordinatorlayout.Widget.CoordinatorLayout
xmlns:androID="http://schemas.androID.com/apk/res/androID"
androID:layout_wIDth="match_parent"
androID:layout_height="67dp"
androID:background="@drawable/Listitem_bg">
<TextVIEw
androID:ID="@+ID/musicname"
androID:layout_wIDth="wrap_content"
androID:layout_height="wrap_content"
androID:gravity="center_vertical"
androID:layout_gravity="center_vertical"
androID:text="Young Gods"
androID:textSize="22sp"
androID:layout_marginleft="8dp"/>
<TextVIEw
androID:ID="@+ID/musictime"
androID:layout_wIDth="wrap_content"
androID:layout_height="wrap_content"
androID:layout_marginleft="262dp"
androID:layout_margintop="30dp"
androID:gravity="center"
androID:text="3'11'"
androID:textSize="12sp" />
<ImageVIEw
androID:ID="@+ID/playmusic"
androID:layout_wIDth="30dp"
androID:layout_height="30dp"
androID:layout_gravity="center_vertical"
androID:layout_marginleft="302dp"
androID:src="@drawable/play"/>
</androIDx.coordinatorlayout.Widget.CoordinatorLayout>
<linearLayout
androID:layout_wIDth="match_parent"
androID:layout_height="15dp"
androID:layout_gravity="center"
androID:background="#00000000" />
</linearLayout>

接下来需要创建一个class用来自定义自己的适配器
内容如下:
//创建Music类
class Music(val musicname:String,val musictime:String,val playimg:Int){}
//创建Music的adapter
class MusicAdapter(val musicList:List<Music>): RecyclerVIEw.Adapter<MusicAdapter.VIEwHolder>(){
//添加音乐文件函数
interface OnItemClickListener {//再这里创建一个接口,使得在onCreate函数中能够监听每一个item的点击事件
fun onItemClick(vIEw: VIEw?, position: Int)
}
private var mOnItemClickListener: OnItemClickListener?=null
fun setonItemClickListener(mOnItemClickListener: OnItemClickListener?) {
this.mOnItemClickListener=mOnItemClickListener
}

inner class VIEwHolder(vIEw: VIEw): RecyclerVIEw.VIEwHolder(vIEw){
val musicname=vIEw.musicname
val musictime=vIEw.musictime
val playimg=vIEw.playmusic
}

overrIDe fun onCreateVIEwHolder(parent: VIEwGroup, vIEwType: Int): VIEwHolder {
val vIEw= LayoutInflater.from(parent.context).inflate(R.layout.music_Listitem,parent,false)
val holder=VIEwHolder(vIEw)
return holder
}

overrIDe fun onBindVIEwHolder(holder: VIEwHolder, position: Int) {
val musicList=musicList[position]
holder.musicname.text=musicList.musicname
holder.musictime.text=musicList.musictime
holder.playimg.setimageResource(musicList.playimg)
if (mOnItemClickListener != null) {
holder.itemVIEw.setonClickListener {
val position = holder.layoutposition
mOnItemClickListener!!.onItemClick(holder.itemVIEw, position)
}
}
}

overrIDe fun getItemCount(): Int {
return musicList.size
}
}

这些准备工作都做完后就要在onCreate的Kotlin文件中添加点击后触发的事件
首先声明一下几个基础变量:
//初始化音乐播放器
val mediaPlayer= MediaPlayer()
// 实例化Music类
val musicList=ArrayList<Music>()
//获取item的position
var playNum:Int=-1
//获取音乐名称
lateinit var musicname:String
//判断是否单曲循环
var issinglePlay=false

紧接着就要在这个RecyclervIEw里面加入适配器了:
//        添加musciAdapter
val MusicAdapter = MusicAdapter(musicList)
initmusic()
musicsList.layoutManager = linearlayoutmanager(this)
musicsList.adapter = MusicAdapter
其中initmusic是自己写的函数,为了在初始状态加入不同的item
//    自定义函数,添加music信息
private fun initmusic() {
musicList.add(Music("柴火燃烧","1'23'",R.drawable.play,0))
musicList.add(Music("风雪木屋","1'23'",R.drawable.play,0))
musicList.add(Music("哈尔的移动城堡","1'23'",R.drawable.play,0))
musicList.add(Music("雷雨天气","1'23'",R.drawable.play,0))
musicList.add(Music("日式温泉","1'23'",R.drawable.play,0))
musicList.add(Music("烟袋斜街","1'23'",R.drawable.play,0))
musicList.add(Music("雨声","1'23'",R.drawable.play,R.drawable.locked))
}
在声明变量的时候我们可以看到有一个初始化音乐播放器,所以我们将自定义一个函数用来寻找音乐资源添加到音乐播放器中,并且可以控制音乐的状态
//自定义播放音乐
private fun initMediaPlayer(musicname:String?){
val assetManager=assets
val fd=assetManager.openFd(musicname+".mp3")
mediaPlayer.setDataSource(fd.fileDescriptor,fd.startOffset,fd.length)
mediaPlayer.prepare()
}
至于musicname如何获取我们会运用到findVIEwHolderForAdapterposition(position)这个函数
一切都准备就绪了,接下来就是要监听点击事件。找到我们的adapter
//点击播放音乐
MusicAdapter.setonItemClickListener(object : MusicAdapter.OnItemClickListener {
overrIDe fun onItemClick(vIEw: VIEw?, position: Int) {
if (!mediaPlayer.isPlaying) {
if (playNum == position) {
musicsList.findVIEwHolderForAdapterposition(position)?.itemVIEw?.playmusic?.setimageResource(R.drawable.pause)
mediaPlayer.start()
} else {
mediaPlayer.reset()
musicsList.findVIEwHolderForAdapterposition(playNum)?.itemVIEw?.playmusic?.setimageResource(R.drawable.play)
playNum = position
musicname = musicsList.findVIEwHolderForAdapterposition(position)?.itemVIEw?.musicname?.text.toString()
musicsList.findVIEwHolderForAdapterposition(position)?.itemVIEw?.playmusic?.setimageResource(R.drawable.pause)
initMediaPlayer(musicname)
mediaPlayer.start()
}
} else if (mediaPlayer.isPlaying) {
if (playNum != position) {
musicsList.findVIEwHolderForAdapterposition(playNum)?.itemVIEw?.playmusic?.setimageResource(R.drawable.play)
playNum = position
mediaPlayer.reset()
musicname = musicsList.findVIEwHolderForAdapterposition(position)?.itemVIEw?.musicname?.text.toString()
musicsList.findVIEwHolderForAdapterposition(position)?.itemVIEw?.playmusic?.setimageResource(R.drawable.pause)
initMediaPlayer(musicname)
mediaPlayer.start()
} else {
mediaPlayer.pause()
musicsList.findVIEwHolderForAdapterposition(position)?.itemVIEw?.playmusic?.setimageResource(R.drawable.play)
}
}
}
})
可以看到监听事件函数里面就会返回position的值,我们之所以还要声明另外一个playNum就是为了判断本次点击和下一次点击的item位置是否相同,
以便决定是停止播放还是暂停播放。
其实在这里我们还是没有实现循环这个功能,只是可以点击播放音乐或者切换、暂停。为了能够监听到是否已经播放完毕我们可以使用setonCompletionListener,
每当播放完毕之后都要重置一下mediaPlayer然后进行判断是否单曲循环也就是之前声明的变量issinglePlay。紧接着就可以根据这两种情况来实现列表循环或者
单曲循环了。
mediaPlayer.setonCompletionListener {
mediaPlayer.reset()
if(!issinglePlay) {
if (musicsList.findVIEwHolderForAdapterposition(playNum + 1) != null) {
musicsList.findVIEwHolderForAdapterposition(playNum)?.itemVIEw?.playmusic?.setimageResource(R.drawable.play)
playNum = playNum + 1
musicsList.findVIEwHolderForAdapterposition(playNum)?.itemVIEw?.playmusic?.setimageResource(R.drawable.pause)
musicname = musicsList.findVIEwHolderForAdapterposition(playNum)?.itemVIEw?.musicname?.text.toString()
initMediaPlayer(musicname)
mediaPlayer.start()
} else {
musicsList.findVIEwHolderForAdapterposition(playNum)?.itemVIEw?.playmusic?.setimageResource(R.drawable.play)
playNum = 0
musicsList.findVIEwHolderForAdapterposition(playNum)?.itemVIEw?.playmusic?.setimageResource(R.drawable.pause)
musicname = musicsList.findVIEwHolderForAdapterposition(playNum)?.itemVIEw?.musicname?.text.toString()
initMediaPlayer(musicname)
mediaPlayer.start()
}
} else{
musicname = musicsList.findVIEwHolderForAdapterposition(playNum)?.itemVIEw?.musicname?.text.toString()
initMediaPlayer(musicname)
mediaPlayer.start()
}
}
到这里就已经结束了,我们不仅可以点击任何一个音乐播放,还可以切换循环的类型。


总结

以上是内存溢出为你收集整理的实现音乐列表循环或者单曲循环全部内容,希望文章能够帮你解决实现音乐列表循环或者单曲循环所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1055233.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存