diff --git a/app/src/main/java/com/woka/modules/wokasongs/WokaSongsAdapter.kt b/app/src/main/java/com/woka/modules/wokasongs/WokaSongsAdapter.kt index 6590af1..a3a1467 100644 --- a/app/src/main/java/com/woka/modules/wokasongs/WokaSongsAdapter.kt +++ b/app/src/main/java/com/woka/modules/wokasongs/WokaSongsAdapter.kt @@ -1,6 +1,9 @@ package com.woka.modules.wokasongs import android.content.Context +import android.os.Handler +import android.os.Looper +import android.util.Log import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView @@ -9,34 +12,92 @@ import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.MediaItem import com.google.android.exoplayer2.PlaybackException import com.google.android.exoplayer2.Player +import com.google.android.exoplayer2.Player.EVENT_IS_LOADING_CHANGED import com.woka.R import com.woka.databinding.WokaSongViewHolderBinding import com.woka.modules.wokasongs.models.SongData +import com.woka.utils.TAG +import com.woka.utils.formatTime import com.woka.utils.hide import com.woka.utils.show +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlin.math.log class WokaSongsAdapter(context: Context): RecyclerView.Adapter() { + companion object{ + private const val CURRENT_TIME_CHANGED = 123 + private const val PLAY_BACK_CHANGED = 124 + } + inner class SongViewHolder(val binding: WokaSongViewHolderBinding): ViewHolder(binding.root) - private var player: ExoPlayer + private var player = ExoPlayer.Builder(context).build() private var currentPlayingPos = -1 private var songList = mutableListOf() + private val lock = Any() + + private val handler: Handler = Handler(Looper.getMainLooper()) + private val updateProgressAction: Runnable = object : Runnable { + override fun run() { + if (currentPlayingPos >= 0 && player.isPlaying){ + notifyItemChanged(currentPlayingPos, CURRENT_TIME_CHANGED) + } + + handler.postDelayed(this, 1000) + } + + } + init { - player = ExoPlayer.Builder(context).build() player.addListener(object : Player.Listener{ override fun onEvents(player: Player, events: Player.Events) { super.onEvents(player, events) - if (currentPlayingPos >= 0) - notifyItemChanged(currentPlayingPos) + if (currentPlayingPos >= 0){ + if (events.containsAny(ExoPlayer.EVENT_IS_LOADING_CHANGED, + ExoPlayer.EVENT_IS_PLAYING_CHANGED)){ + + notifyItemChanged(currentPlayingPos, PLAY_BACK_CHANGED) + } + } + } + + override fun onPlaybackStateChanged(playbackState: Int) { + super.onPlaybackStateChanged(playbackState) + if (playbackState == ExoPlayer.STATE_ENDED){ + player.removeListener(this) + player.pause() + player.addListener(this) + + val lastPosition = currentPlayingPos + currentPlayingPos = -1 + notifyItemChanged(lastPosition, PLAY_BACK_CHANGED) + } + } + + override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) { + super.onMediaItemTransition(mediaItem, reason) + if (reason == ExoPlayer.MEDIA_ITEM_TRANSITION_REASON_AUTO){ + player.removeListener(this) + player.pause() + player.addListener(this) + + val lastPosition = currentPlayingPos + currentPlayingPos = -1 + notifyItemChanged(lastPosition, PLAY_BACK_CHANGED) + } } override fun onPlayerError(error: PlaybackException) { super.onPlayerError(error) - if (currentPlayingPos >= 0) - notifyItemChanged(currentPlayingPos) + if (currentPlayingPos >= 0) { + notifyItemChanged(currentPlayingPos, PLAY_BACK_CHANGED) + } } }) } @@ -44,6 +105,8 @@ class WokaSongsAdapter(context: Context): RecyclerView.Adapter + ) { + if (payloads.isNotEmpty()){ + synchronized(lock){ + holder.binding.apply { + when (payloads[0]){ + CURRENT_TIME_CHANGED -> { + if (currentPlayingPos == position){ + currentTime.text = player.currentPosition.formatTime() + }else{ + currentTime.text = root.context.getString(R.string._00_00) + } + } + PLAY_BACK_CHANGED -> { + if (currentPlayingPos == holder.absoluteAdapterPosition){ + if (player.isPlaying){ + progressBar.post { + progressBar.show() + playBtn.setImageResource(R.drawable.ic_pause) + playBtn.show() + progressBar.hide() + } + }else if (player.isLoading){ + playBtn.hide() + progressBar.show() + }else{ + playBtn.show() + playBtn.setImageResource(R.drawable.ic_play) + progressBar.hide() + } + }else{ + playBtn.show() + playBtn.setImageResource(R.drawable.ic_play) + progressBar.hide() + } + } + else -> super.onBindViewHolder(holder, position, payloads) + } + } + } + }else super.onBindViewHolder(holder, position, payloads) + } + override fun onBindViewHolder(holder: SongViewHolder, position: Int) { if (position >= songList.size) return val songData = songList[position] holder.binding.apply { title.text = songData.title + totalTime.text = try { if (songData.song_duration?.split(":")?.get(0)?.toInt() == 0) songData.song_duration.substring(3) @@ -70,6 +180,12 @@ class WokaSongsAdapter(context: Context): RecyclerView.Adapter= 0) notifyItemChanged(currentPlayingPos) - + val lastPlayingPos = currentPlayingPos currentPlayingPos = holder.absoluteAdapterPosition - + if (lastPlayingPos >= 0) { + notifyItemChanged(lastPlayingPos, PLAY_BACK_CHANGED) + } player.seekTo(holder.absoluteAdapterPosition, 0) player.play() } @@ -96,18 +212,20 @@ class WokaSongsAdapter(context: Context): RecyclerView.Adapter 0) { + String.format("%02d:%02d:%02d", hours, minutes, seconds) + } else { + String.format("%02d:%02d", minutes, seconds) + } } \ No newline at end of file diff --git a/app/src/main/res/layout/woka_song_view_holder.xml b/app/src/main/res/layout/woka_song_view_holder.xml index 3324a75..1cf1f73 100644 --- a/app/src/main/res/layout/woka_song_view_holder.xml +++ b/app/src/main/res/layout/woka_song_view_holder.xml @@ -29,16 +29,16 @@ WOKA Songs WOKA Do you want to exit from the WOKA app? + 00:00 + / \ No newline at end of file