재생 목록 플레이어

- 재생 목록 리스트 추가
This commit is contained in:
klaus 2024-12-13 23:21:58 +09:00
parent 8c8b8c1747
commit 057e21570b
5 changed files with 107 additions and 23 deletions

View File

@ -4,6 +4,7 @@ import android.app.Dialog
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.os.Handler
import android.os.Looper
@ -22,15 +23,17 @@ import androidx.media3.session.MediaController
import androidx.media3.session.SessionCommand
import androidx.media3.session.SessionResult
import androidx.media3.session.SessionToken
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.CircleCropTransformation
import coil.transform.RoundedCornersTransformation
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.orhanobut.logger.Logger
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.audio_content.playlist.detail.AudioContentPlaylistContent
import kr.co.vividnext.sodalive.audio_content.playlist.detail.AudioContentPlaylistDetailAdapter
import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
@ -46,6 +49,7 @@ class AudioContentPlayerFragment(
) : BottomSheetDialogFragment() {
private lateinit var loadingDialog: LoadingDialog
private lateinit var adapter: AudioContentPlaylistDetailAdapter
private lateinit var binding: FragmentAudioContentPlayerBinding
private val viewModel: AudioContentPlayerViewModel by viewModel()
@ -108,6 +112,50 @@ class AudioContentPlayerFragment(
private fun setupView() {
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
binding.ivClose.setOnClickListener { dismiss() }
binding.ivPlaylist.setOnClickListener {
viewModel.toggleShowPlayList()
}
adapter = AudioContentPlaylistDetailAdapter()
val recyclerView = binding.rvPlaylistContent
recyclerView.setHasFixedSize(true)
recyclerView.layoutManager = LinearLayoutManager(
requireContext(),
LinearLayoutManager.VERTICAL,
false
)
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
outRect.left = 0
outRect.right = 0
when (parent.getChildAdapterPosition(view)) {
0 -> {
outRect.top = 0
outRect.bottom = 6.7f.dpToPx().toInt()
}
adapter.itemCount - 1 -> {
outRect.top = 6.7f.dpToPx().toInt()
outRect.bottom = 0
}
else -> {
outRect.top = 6.7f.dpToPx().toInt()
outRect.bottom = 6.7f.dpToPx().toInt()
}
}
}
})
recyclerView.adapter = adapter
}
private fun bindData() {
@ -125,6 +173,20 @@ class AudioContentPlayerFragment(
loadingDialog.dismiss()
}
}
viewModel.isShowPlaylistLiveData.observe(viewLifecycleOwner) {
if (it) {
binding.ivCover.visibility = View.GONE
binding.rvPlaylistContent.visibility = View.VISIBLE
binding.ivPlaylist.setBackgroundResource(
R.drawable.bg_round_corner_6_7_cc333333
)
} else {
binding.ivCover.visibility = View.VISIBLE
binding.rvPlaylistContent.visibility = View.GONE
binding.ivPlaylist.setBackgroundResource(0)
}
}
}
private fun connectPlayerService() {
@ -209,6 +271,7 @@ class AudioContentPlayerFragment(
}
val sessionCommand = SessionCommand("UPDATE_PLAYLIST", Bundle.EMPTY)
mediaController!!.sendCustomCommand(sessionCommand, extras)
adapter.updateItems(playlist)
} else {
context?.let {
val sessionCommand = SessionCommand("GET_PLAYLIST", Bundle.EMPTY)
@ -222,8 +285,7 @@ class AudioContentPlayerFragment(
Constants.EXTRA_AUDIO_CONTENT_PLAYLIST,
AudioContentPlaylistContent::class.java
)
Logger.e("playlist: $data")
adapter.updateItems(data ?: listOf())
}
},
ContextCompat.getMainExecutor(it)
@ -315,7 +377,7 @@ class AudioContentPlayerFragment(
binding.ivCover.load(it.artworkUri) {
crossfade(true)
placeholder(R.drawable.ic_place_holder)
transformations(RoundedCornersTransformation(12f.dpToPx()))
transformations(RoundedCornersTransformation(8f.dpToPx()))
}
}
}

View File

@ -13,7 +13,15 @@ class AudioContentPlayerViewModel : BaseViewModel() {
val isLoading: LiveData<Boolean>
get() = _isLoading
private var _isShowPlaylistLiveData = MutableLiveData(false)
val isShowPlaylistLiveData: LiveData<Boolean>
get() = _isShowPlaylistLiveData
fun setLoading(loading: Boolean) {
_isLoading.value = loading
}
fun toggleShowPlayList() {
_isShowPlaylistLiveData.value = !_isShowPlaylistLiveData.value!!
}
}

View File

@ -67,16 +67,16 @@ class AudioContentPlaylistDetailActivity : BaseActivity<ActivityAudioContentPlay
SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
// 특정 키에 대한 값이 변경될 때 UI 업데이트
if (key == Constants.PREF_IS_PLAYER_SERVICE_RUNNING) {
handler.postDelayed(
{
if (sharedPreferences.getBoolean(key, false)) {
if (sharedPreferences.getBoolean(key, false)) {
handler.postDelayed(
{
initAndVisibleMiniPlayer()
} else {
deInitMiniPlayer()
}
},
2000
)
},
1500
)
} else {
deInitMiniPlayer()
}
}
}

View File

@ -66,16 +66,16 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
// 특정 키에 대한 값이 변경될 때 UI 업데이트
if (key == Constants.PREF_IS_PLAYER_SERVICE_RUNNING) {
handler.postDelayed(
{
if (sharedPreferences.getBoolean(key, false)) {
if (sharedPreferences.getBoolean(key, false)) {
handler.postDelayed(
{
initAndVisibleMiniPlayer()
} else {
deInitMiniPlayer()
}
},
2000
)
},
1500
)
} else {
deInitMiniPlayer()
}
}
}

View File

@ -12,7 +12,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_close_white"
android:src="@drawable/ic_bottom_white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -26,6 +26,7 @@
android:maxLines="2"
android:textColor="@color/color_eeeeee"
android:textSize="16sp"
android:padding="5dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_close"
@ -59,12 +60,24 @@
android:layout_width="240dp"
android:layout_height="240dp"
android:contentDescription="@null"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/sb_progress"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_creator_profile"
tools:src="@drawable/img_compleate_book" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_playlist_content"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginVertical="20dp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/sb_progress"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_creator_profile" />
<SeekBar
android:id="@+id/sb_progress"
android:layout_width="0dp"
@ -134,6 +147,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:padding="5dp"
android:src="@drawable/ic_playlist"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />