오디션 지원자
- 오디오 재생시 시간과 ProgressBar 추가
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package kr.co.vividnext.sodalive.audition.applicant
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
@@ -8,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.load
|
||||
import coil.transform.CircleCropTransformation
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.common.Utils
|
||||
import kr.co.vividnext.sodalive.databinding.ItemAuditionApplicantBinding
|
||||
|
||||
class AuditionApplicantListAdapter(
|
||||
@@ -16,6 +19,8 @@ class AuditionApplicantListAdapter(
|
||||
) : ListAdapter<GetAuditionRoleApplicantItem, AuditionApplicantListAdapter.ViewHolder>(DiffCallback()) {
|
||||
|
||||
private var currentPlayingIndex: Int = -1
|
||||
private var currentTotalDuration: Int = 0
|
||||
private var currentTime: Int = 0
|
||||
private var isPlaying: Boolean = false
|
||||
|
||||
class DiffCallback : DiffUtil.ItemCallback<GetAuditionRoleApplicantItem>() {
|
||||
@@ -37,9 +42,14 @@ class AuditionApplicantListAdapter(
|
||||
inner class ViewHolder(
|
||||
private val binding: ItemAuditionApplicantBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun bind(item: GetAuditionRoleApplicantItem) {
|
||||
binding.llVote.setOnClickListener { onClickVote(bindingAdapterPosition) }
|
||||
binding.ivProfile.setOnClickListener {
|
||||
if (currentPlayingIndex != bindingAdapterPosition) {
|
||||
currentTime = 0
|
||||
currentTotalDuration = 0
|
||||
}
|
||||
onClickPlayOrPause(bindingAdapterPosition, item.applicantId, item.voiceUrl)
|
||||
}
|
||||
|
||||
@@ -58,6 +68,31 @@ class AuditionApplicantListAdapter(
|
||||
R.drawable.ic_audition_play
|
||||
}
|
||||
)
|
||||
|
||||
if (bindingAdapterPosition == currentPlayingIndex) {
|
||||
binding.tvTotalDuration.visibility = View.VISIBLE
|
||||
binding.tvCurrentTime.visibility = View.VISIBLE
|
||||
binding.sbProgress.visibility = View.VISIBLE
|
||||
|
||||
binding.sbProgress.max = currentTotalDuration
|
||||
binding.sbProgress.progress = currentTime
|
||||
|
||||
binding.tvTotalDuration.text =
|
||||
"/${
|
||||
Utils.convertDurationToString(
|
||||
currentTotalDuration,
|
||||
showHours = false
|
||||
)
|
||||
}"
|
||||
binding.tvCurrentTime.text = Utils.convertDurationToString(
|
||||
currentTime,
|
||||
showHours = false
|
||||
)
|
||||
} else {
|
||||
binding.tvTotalDuration.visibility = View.GONE
|
||||
binding.tvCurrentTime.visibility = View.GONE
|
||||
binding.sbProgress.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,4 +116,14 @@ class AuditionApplicantListAdapter(
|
||||
notifyItemChanged(previousIndex)
|
||||
notifyItemChanged(currentPlayingIndex)
|
||||
}
|
||||
|
||||
fun updateTotalDuration(totalDuration: Int) {
|
||||
currentTotalDuration = totalDuration
|
||||
notifyItemChanged(currentPlayingIndex)
|
||||
}
|
||||
|
||||
fun updateCurrentTime(currentTime: Int) {
|
||||
this.currentTime = currentTime
|
||||
notifyItemChanged(currentPlayingIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,29 +5,46 @@ import android.content.Intent
|
||||
import android.media.AudioAttributes
|
||||
import android.media.MediaPlayer
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.widget.Toast
|
||||
import com.orhanobut.logger.Logger
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import kr.co.vividnext.sodalive.audio_content.AudioContentPlayService
|
||||
import kr.co.vividnext.sodalive.audio_content.player.AudioContentPlayerService
|
||||
import java.io.IOException
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
class AuditionApplicantMediaPlayerManager(
|
||||
private val context: Context,
|
||||
private val updateUI: (Int, Boolean) -> Unit
|
||||
private val updatePlayPauseState: (Int, Boolean) -> Unit,
|
||||
private val updateTotalDuration: (Int) -> Unit,
|
||||
private val updateCurrentTime: (Int) -> Unit,
|
||||
private val showLoadingDialog: (Boolean) -> Unit
|
||||
) {
|
||||
private var mediaPlayer: MediaPlayer? = null
|
||||
private var currentPlayingApplicantId: Long = -1
|
||||
private var currentPlayingPosition: Int = -1
|
||||
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private var changeMediaPlayerPositionRunnable = object : Runnable {
|
||||
override fun run() {
|
||||
if (mediaPlayer != null) {
|
||||
updateCurrentTime(mediaPlayer!!.currentPosition)
|
||||
}
|
||||
handler.postDelayed(this, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
fun pauseContent() {
|
||||
mediaPlayer?.pause()
|
||||
updateUI(currentPlayingPosition, false)
|
||||
updatePlayPauseState(currentPlayingPosition, false)
|
||||
}
|
||||
|
||||
private fun resumeContent() {
|
||||
pauseAudioContentService()
|
||||
mediaPlayer?.start()
|
||||
updateUI(currentPlayingPosition, true)
|
||||
updatePlayPauseState(currentPlayingPosition, true)
|
||||
}
|
||||
|
||||
fun stopContent() {
|
||||
@@ -38,22 +55,27 @@ class AuditionApplicantMediaPlayerManager(
|
||||
}
|
||||
currentPlayingApplicantId = -1
|
||||
currentPlayingPosition = -1
|
||||
updateUI(currentPlayingPosition, false)
|
||||
updatePlayPauseState(currentPlayingPosition, false)
|
||||
handler.removeCallbacks(changeMediaPlayerPositionRunnable)
|
||||
}
|
||||
|
||||
fun toggleContent(position: Int, applicantId: Long, voiceUrl: String) {
|
||||
if (currentPlayingApplicantId == applicantId && currentPlayingPosition == position) {
|
||||
if (mediaPlayer?.isPlaying == true) {
|
||||
pauseContent()
|
||||
handler.removeCallbacks(changeMediaPlayerPositionRunnable)
|
||||
} else {
|
||||
resumeContent()
|
||||
handler.postDelayed(changeMediaPlayerPositionRunnable, 1000)
|
||||
}
|
||||
} else {
|
||||
playContent(position, applicantId, voiceUrl)
|
||||
handler.postDelayed(changeMediaPlayerPositionRunnable, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
private fun playContent(position: Int, applicantId: Long, voiceUrl: String) {
|
||||
showLoadingDialog(true)
|
||||
pauseAudioContentService()
|
||||
stopContent()
|
||||
|
||||
@@ -73,15 +95,18 @@ class AuditionApplicantMediaPlayerManager(
|
||||
prepareAsync() // 비동기적으로 준비
|
||||
setOnPreparedListener {
|
||||
start()
|
||||
updateUI(currentPlayingPosition, true)
|
||||
updateTotalDuration(duration)
|
||||
updatePlayPauseState(currentPlayingPosition, true)
|
||||
showLoadingDialog(false)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(context, "콘텐츠를 재생하지 못했습니다.\n다시 시도해 주세요", Toast.LENGTH_SHORT).show()
|
||||
showLoadingDialog(false)
|
||||
}
|
||||
|
||||
setOnCompletionListener {
|
||||
updateUI(currentPlayingPosition, false)
|
||||
updatePlayPauseState(currentPlayingPosition, false)
|
||||
currentPlayingApplicantId = -1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,10 +91,24 @@ class AuditionRoleDetailActivity : BaseActivity<ActivityAuditionRoleDetailBindin
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
mediaPlayerManager = AuditionApplicantMediaPlayerManager(
|
||||
this
|
||||
) { position, isPlaying ->
|
||||
adapter.updatePlayingIndex(position, isPlaying)
|
||||
}
|
||||
context = this,
|
||||
updatePlayPauseState = { position, isPlaying ->
|
||||
adapter.updatePlayingIndex(position, isPlaying)
|
||||
},
|
||||
updateTotalDuration = { duration ->
|
||||
adapter.updateTotalDuration(totalDuration = duration)
|
||||
},
|
||||
updateCurrentTime = { currentTime ->
|
||||
adapter.updateCurrentTime(currentTime)
|
||||
},
|
||||
showLoadingDialog = {
|
||||
if (it) {
|
||||
loadingDialog.show(screenWidth, "")
|
||||
} else {
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
bindData()
|
||||
viewModel.getAuditionRoleDetail(auditionRoleId = auditionRoleId)
|
||||
@@ -197,6 +211,8 @@ class AuditionRoleDetailActivity : BaseActivity<ActivityAuditionRoleDetailBindin
|
||||
)
|
||||
|
||||
val recyclerView = binding.rvApplicant
|
||||
recyclerView.setHasFixedSize(true)
|
||||
recyclerView.itemAnimator = null
|
||||
recyclerView.layoutManager = LinearLayoutManager(
|
||||
applicationContext,
|
||||
LinearLayoutManager.VERTICAL,
|
||||
|
||||
Reference in New Issue
Block a user