其他分享
首页 > 其他分享> > 实现音乐列表循环或者单曲循环

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

作者:互联网

无论是单曲循环还是列表循环都要先有一个音乐列表,在这里我使用了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()
}
}
到这里就已经结束了,我们不仅可以点击任何一个音乐播放,还可以切换循环的类型。


标签:musicname,musicslist,layout,playNum,列表,循环,android,单曲,drawable
来源: https://www.cnblogs.com/starpython/p/14101070.html