parent
6da3192fe8
commit
29595670af
|
@ -139,6 +139,7 @@ class AudioContentPlayerFragment(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startPlayerService(context: Context) {
|
private fun startPlayerService(context: Context) {
|
||||||
|
Toast.makeText(requireContext(), "startPlayerService", Toast.LENGTH_LONG).show()
|
||||||
val serviceIntent = Intent(context, AudioContentPlayerService::class.java)
|
val serviceIntent = Intent(context, AudioContentPlayerService::class.java)
|
||||||
context.startService(serviceIntent)
|
context.startService(serviceIntent)
|
||||||
}
|
}
|
||||||
|
@ -232,6 +233,14 @@ class AudioContentPlayerFragment(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayerUI() {
|
private fun updatePlayerUI() {
|
||||||
|
binding.ivPlayOrPause.setImageResource(
|
||||||
|
if (mediaController!!.isPlaying) {
|
||||||
|
R.drawable.ic_player_pause
|
||||||
|
} else {
|
||||||
|
R.drawable.ic_player_play
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.ivPlayOrPause.setOnClickListener {
|
binding.ivPlayOrPause.setOnClickListener {
|
||||||
mediaController?.let {
|
mediaController?.let {
|
||||||
if (it.playWhenReady) {
|
if (it.playWhenReady) {
|
||||||
|
|
|
@ -47,8 +47,6 @@ class AudioContentPlayerService : MediaSessionService() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SharedPreferenceManager.isPlayerServiceRunning = true
|
|
||||||
|
|
||||||
initPlayer()
|
initPlayer()
|
||||||
initMediaSession()
|
initMediaSession()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -121,6 +119,7 @@ class AudioContentPlayerService : MediaSessionService() {
|
||||||
session: MediaSession,
|
session: MediaSession,
|
||||||
controller: MediaSession.ControllerInfo
|
controller: MediaSession.ControllerInfo
|
||||||
): MediaSession.ConnectionResult {
|
): MediaSession.ConnectionResult {
|
||||||
|
SharedPreferenceManager.isPlayerServiceRunning = true
|
||||||
val allowedCommands = MediaSession.ConnectionResult.DEFAULT_SESSION_COMMANDS
|
val allowedCommands = MediaSession.ConnectionResult.DEFAULT_SESSION_COMMANDS
|
||||||
.buildUpon()
|
.buildUpon()
|
||||||
.add(SessionCommand("UPDATE_PLAYLIST", Bundle.EMPTY))
|
.add(SessionCommand("UPDATE_PLAYLIST", Bundle.EMPTY))
|
||||||
|
|
|
@ -2,15 +2,9 @@ package kr.co.vividnext.sodalive.audio_content.player
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
import kr.co.vividnext.sodalive.base.BaseViewModel
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
|
|
||||||
class AudioContentPlayerViewModel(
|
class AudioContentPlayerViewModel : BaseViewModel() {
|
||||||
private val repository: AudioContentGenerateUrlRepository
|
|
||||||
) : BaseViewModel() {
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
private val _toastLiveData = MutableLiveData<String?>()
|
||||||
val toastLiveData: LiveData<String?>
|
val toastLiveData: LiveData<String?>
|
||||||
get() = _toastLiveData
|
get() = _toastLiveData
|
||||||
|
|
|
@ -14,6 +14,7 @@ import android.widget.Toast
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
|
import androidx.media3.common.MediaMetadata
|
||||||
import androidx.media3.common.Player
|
import androidx.media3.common.Player
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.session.MediaController
|
import androidx.media3.session.MediaController
|
||||||
|
@ -73,7 +74,7 @@ class AudioContentPlaylistDetailActivity : BaseActivity<ActivityAudioContentPlay
|
||||||
deInitMiniPlayer()
|
deInitMiniPlayer()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
500
|
2000
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,6 +101,16 @@ class AudioContentPlaylistDetailActivity : BaseActivity<ActivityAudioContentPlay
|
||||||
{
|
{
|
||||||
mediaController = mediaControllerFuture.get()
|
mediaController = mediaControllerFuture.get()
|
||||||
setupMediaController()
|
setupMediaController()
|
||||||
|
updateMediaMetadata(mediaController?.mediaMetadata)
|
||||||
|
|
||||||
|
binding.ivPlayOrPause.setImageResource(
|
||||||
|
if (mediaController!!.isPlaying) {
|
||||||
|
R.drawable.ic_player_pause
|
||||||
|
} else {
|
||||||
|
R.drawable.ic_player_play
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
binding.ivPlayOrPause.setOnClickListener {
|
binding.ivPlayOrPause.setOnClickListener {
|
||||||
mediaController?.let {
|
mediaController?.let {
|
||||||
if (it.playWhenReady) {
|
if (it.playWhenReady) {
|
||||||
|
@ -114,6 +125,19 @@ class AudioContentPlaylistDetailActivity : BaseActivity<ActivityAudioContentPlay
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateMediaMetadata(metadata: MediaMetadata?) {
|
||||||
|
metadata?.let {
|
||||||
|
binding.tvPlayerTitle.text = it.title
|
||||||
|
binding.tvPlayerNickname.text = it.artist
|
||||||
|
|
||||||
|
binding.ivPlayerCover.load(it.artworkUri) {
|
||||||
|
crossfade(true)
|
||||||
|
placeholder(R.drawable.ic_place_holder)
|
||||||
|
transformations(RoundedCornersTransformation(4f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupMediaController() {
|
private fun setupMediaController() {
|
||||||
if (mediaController == null) {
|
if (mediaController == null) {
|
||||||
deInitMiniPlayer()
|
deInitMiniPlayer()
|
||||||
|
@ -122,16 +146,7 @@ class AudioContentPlaylistDetailActivity : BaseActivity<ActivityAudioContentPlay
|
||||||
|
|
||||||
mediaController!!.addListener(object : Player.Listener {
|
mediaController!!.addListener(object : Player.Listener {
|
||||||
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
||||||
mediaItem?.mediaMetadata?.let {
|
updateMediaMetadata(mediaItem?.mediaMetadata)
|
||||||
binding.ivPlayerCover.load(it.artworkUri) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(RoundedCornersTransformation(5.3f.dpToPx()))
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvPlayerTitle.text = it.title
|
|
||||||
binding.tvPlayerNickname.text = it.artist
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPlayWhenReadyChanged(playWhenReady: Boolean, reason: Int) {
|
override fun onPlayWhenReadyChanged(playWhenReady: Boolean, reason: Int) {
|
||||||
|
|
|
@ -278,7 +278,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
||||||
viewModel { AudioContentPlaylistDetailViewModel(get()) }
|
viewModel { AudioContentPlaylistDetailViewModel(get()) }
|
||||||
viewModel { AudioContentPlaylistCreateViewModel(get()) }
|
viewModel { AudioContentPlaylistCreateViewModel(get()) }
|
||||||
viewModel { AudioContentPlaylistModifyViewModel(get()) }
|
viewModel { AudioContentPlaylistModifyViewModel(get()) }
|
||||||
viewModel { AudioContentPlayerViewModel(get()) }
|
viewModel { AudioContentPlayerViewModel() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val repositoryModule = module {
|
private val repositoryModule = module {
|
||||||
|
|
|
@ -59,6 +59,7 @@ import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
@UnstableApi
|
||||||
class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::inflate) {
|
class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::inflate) {
|
||||||
private val viewModel: LiveViewModel by inject()
|
private val viewModel: LiveViewModel by inject()
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
|
@UnstableApi
|
||||||
class LiveNowAllActivity : BaseActivity<ActivityLiveNowAllBinding>(
|
class LiveNowAllActivity : BaseActivity<ActivityLiveNowAllBinding>(
|
||||||
ActivityLiveNowAllBinding::inflate
|
ActivityLiveNowAllBinding::inflate
|
||||||
) {
|
) {
|
||||||
|
@ -96,7 +97,6 @@ class LiveNowAllActivity : BaseActivity<ActivityLiveNowAllBinding>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@UnstableApi
|
|
||||||
private fun enterLiveRoom(roomId: Long) {
|
private fun enterLiveRoom(roomId: Long) {
|
||||||
startService(
|
startService(
|
||||||
Intent(applicationContext, AudioContentPlayService::class.java).apply {
|
Intent(applicationContext, AudioContentPlayService::class.java).apply {
|
||||||
|
|
|
@ -2,9 +2,11 @@ package kr.co.vividnext.sodalive.main
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -13,6 +15,12 @@ import android.os.Looper
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
|
import androidx.media3.common.MediaItem
|
||||||
|
import androidx.media3.common.MediaMetadata
|
||||||
|
import androidx.media3.common.Player
|
||||||
|
import androidx.media3.common.util.UnstableApi
|
||||||
|
import androidx.media3.session.MediaController
|
||||||
|
import androidx.media3.session.SessionToken
|
||||||
import coil.load
|
import coil.load
|
||||||
import coil.transform.RoundedCornersTransformation
|
import coil.transform.RoundedCornersTransformation
|
||||||
import com.google.firebase.messaging.FirebaseMessaging
|
import com.google.firebase.messaging.FirebaseMessaging
|
||||||
|
@ -23,6 +31,8 @@ import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.audio_content.AudioContentPlayService
|
import kr.co.vividnext.sodalive.audio_content.AudioContentPlayService
|
||||||
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainFragment
|
import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainFragment
|
||||||
|
import kr.co.vividnext.sodalive.audio_content.player.AudioContentPlayerFragment
|
||||||
|
import kr.co.vividnext.sodalive.audio_content.player.AudioContentPlayerService
|
||||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||||
import kr.co.vividnext.sodalive.common.Constants
|
import kr.co.vividnext.sodalive.common.Constants
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
|
@ -39,6 +49,7 @@ import kr.co.vividnext.sodalive.settings.event.EventDetailActivity
|
||||||
import kr.co.vividnext.sodalive.settings.notification.NotificationSettingsDialog
|
import kr.co.vividnext.sodalive.settings.notification.NotificationSettingsDialog
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
|
@UnstableApi
|
||||||
class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::inflate) {
|
class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::inflate) {
|
||||||
|
|
||||||
private val viewModel: MainViewModel by inject()
|
private val viewModel: MainViewModel by inject()
|
||||||
|
@ -47,9 +58,115 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
|
||||||
private lateinit var loadingDialog: LoadingDialog
|
private lateinit var loadingDialog: LoadingDialog
|
||||||
private lateinit var notificationSettingsDialog: NotificationSettingsDialog
|
private lateinit var notificationSettingsDialog: NotificationSettingsDialog
|
||||||
|
|
||||||
|
private var mediaController: MediaController? = null
|
||||||
private val handler = Handler(Looper.getMainLooper())
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
private val audioContentReceiver = AudioContentReceiver()
|
private val audioContentReceiver = AudioContentReceiver()
|
||||||
|
|
||||||
|
private val preferenceChangeListener =
|
||||||
|
SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
|
||||||
|
// 특정 키에 대한 값이 변경될 때 UI 업데이트
|
||||||
|
if (key == Constants.PREF_IS_PLAYER_SERVICE_RUNNING) {
|
||||||
|
handler.postDelayed(
|
||||||
|
{
|
||||||
|
if (sharedPreferences.getBoolean(key, false)) {
|
||||||
|
initAndVisibleMiniPlayer()
|
||||||
|
} else {
|
||||||
|
deInitMiniPlayer()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
2000
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initAndVisibleMiniPlayer() {
|
||||||
|
binding.clMiniPlayer.visibility = View.VISIBLE
|
||||||
|
binding.clMiniPlayer.setOnClickListener { showPlayerFragment() }
|
||||||
|
binding.ivPlayerStop.setOnClickListener {
|
||||||
|
startService(
|
||||||
|
Intent(applicationContext, AudioContentPlayerService::class.java).apply {
|
||||||
|
action = "STOP_SERVICE"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
connectPlayerService()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun connectPlayerService() {
|
||||||
|
val componentName = ComponentName(applicationContext, AudioContentPlayerService::class.java)
|
||||||
|
val sessionToken = SessionToken(applicationContext, componentName)
|
||||||
|
val mediaControllerFuture =
|
||||||
|
MediaController.Builder(applicationContext, sessionToken).buildAsync()
|
||||||
|
mediaControllerFuture.addListener(
|
||||||
|
{
|
||||||
|
mediaController = mediaControllerFuture.get()
|
||||||
|
setupMediaController()
|
||||||
|
updateMediaMetadata(mediaController?.mediaMetadata)
|
||||||
|
|
||||||
|
binding.ivPlayerPlayOrPause.setImageResource(
|
||||||
|
if (mediaController!!.isPlaying) {
|
||||||
|
R.drawable.ic_player_pause
|
||||||
|
} else {
|
||||||
|
R.drawable.ic_player_play
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.ivPlayerPlayOrPause.setOnClickListener {
|
||||||
|
mediaController?.let {
|
||||||
|
if (it.playWhenReady) {
|
||||||
|
it.pause()
|
||||||
|
} else {
|
||||||
|
it.play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ContextCompat.getMainExecutor(applicationContext)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateMediaMetadata(metadata: MediaMetadata?) {
|
||||||
|
metadata?.let {
|
||||||
|
binding.tvPlayerTitle.text = it.title
|
||||||
|
binding.tvPlayerNickname.text = it.artist
|
||||||
|
|
||||||
|
binding.ivPlayerCover.load(it.artworkUri) {
|
||||||
|
crossfade(true)
|
||||||
|
placeholder(R.drawable.ic_place_holder)
|
||||||
|
transformations(RoundedCornersTransformation(4f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupMediaController() {
|
||||||
|
if (mediaController == null) {
|
||||||
|
deInitMiniPlayer()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaController!!.addListener(object : Player.Listener {
|
||||||
|
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
||||||
|
updateMediaMetadata(mediaItem?.mediaMetadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPlayWhenReadyChanged(playWhenReady: Boolean, reason: Int) {
|
||||||
|
binding.ivPlayerPlayOrPause.setImageResource(
|
||||||
|
if (playWhenReady) {
|
||||||
|
R.drawable.ic_player_pause
|
||||||
|
} else {
|
||||||
|
R.drawable.ic_player_play
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deInitMiniPlayer() {
|
||||||
|
binding.clMiniPlayer.visibility = View.GONE
|
||||||
|
mediaController?.release()
|
||||||
|
mediaController = null
|
||||||
|
}
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent) {
|
override fun onNewIntent(intent: Intent) {
|
||||||
super.onNewIntent(intent)
|
super.onNewIntent(intent)
|
||||||
executeDeeplink(intent)
|
executeDeeplink(intent)
|
||||||
|
@ -64,9 +181,27 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
|
||||||
getMemberInfo()
|
getMemberInfo()
|
||||||
getEventPopup()
|
getEventPopup()
|
||||||
|
|
||||||
|
SharedPreferenceManager.registerOnSharedPreferenceChangeListener(preferenceChangeListener)
|
||||||
|
if (SharedPreferenceManager.isPlayerServiceRunning) {
|
||||||
|
initAndVisibleMiniPlayer()
|
||||||
|
} else {
|
||||||
|
deInitMiniPlayer()
|
||||||
|
}
|
||||||
|
|
||||||
handler.postDelayed({ executeDeeplink(intent) }, 500)
|
handler.postDelayed({ executeDeeplink(intent) }, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
deInitMiniPlayer()
|
||||||
|
SharedPreferenceManager.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener)
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showPlayerFragment() {
|
||||||
|
val playerFragment = AudioContentPlayerFragment(screenWidth, arrayListOf())
|
||||||
|
playerFragment.show(supportFragmentManager, playerFragment.tag)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
val intentFilter = IntentFilter(Constants.ACTION_MAIN_AUDIO_CONTENT_RECEIVER)
|
val intentFilter = IntentFilter(Constants.ACTION_MAIN_AUDIO_CONTENT_RECEIVER)
|
||||||
|
|
|
@ -27,6 +27,7 @@ import kr.co.vividnext.sodalive.settings.terms.TermsActivity
|
||||||
import kr.co.vividnext.sodalive.splash.SplashActivity
|
import kr.co.vividnext.sodalive.splash.SplashActivity
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
|
@UnstableApi
|
||||||
class SettingsActivity : BaseActivity<ActivitySettingsBinding>(ActivitySettingsBinding::inflate) {
|
class SettingsActivity : BaseActivity<ActivitySettingsBinding>(ActivitySettingsBinding::inflate) {
|
||||||
private val logoutDialog: SodaDialog by lazy {
|
private val logoutDialog: SodaDialog by lazy {
|
||||||
SodaDialog(
|
SodaDialog(
|
||||||
|
@ -159,7 +160,6 @@ class SettingsActivity : BaseActivity<ActivitySettingsBinding>(ActivitySettingsB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@UnstableApi
|
|
||||||
private fun logout() {
|
private fun logout() {
|
||||||
startService(
|
startService(
|
||||||
Intent(applicationContext, AudioContentPlayService::class.java).apply {
|
Intent(applicationContext, AudioContentPlayService::class.java).apply {
|
||||||
|
|
|
@ -81,6 +81,76 @@
|
||||||
android:src="@drawable/ic_noti_stop" />
|
android:src="@drawable/ic_noti_stop" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/cl_mini_player"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_above="@+id/ll_tab"
|
||||||
|
android:background="@color/color_222222"
|
||||||
|
android:paddingHorizontal="13.3dp"
|
||||||
|
android:paddingVertical="10.7dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_player_cover"
|
||||||
|
android:layout_width="36.7dp"
|
||||||
|
android:layout_height="36.7dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:src="@mipmap/ic_launcher" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_player_title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="10.7dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:textColor="@color/color_eeeeee"
|
||||||
|
android:textSize="13sp"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/iv_player_play_or_pause"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/iv_player_cover"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/iv_player_cover"
|
||||||
|
tools:text="JFLA 커버곡 Avicii for your self" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_player_nickname"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="2.3dp"
|
||||||
|
android:textColor="@color/color_d2d2d2"
|
||||||
|
android:textSize="11sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/tv_player_title"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/tv_player_title"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/tv_player_title"
|
||||||
|
tools:ignore="SmallSp"
|
||||||
|
tools:text="JFLA 커버곡 Avicii for your self" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_player_play_or_pause"
|
||||||
|
android:layout_width="25dp"
|
||||||
|
android:layout_height="25dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/iv_player_stop"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/iv_player_stop"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/iv_player_stop"
|
||||||
|
tools:src="@drawable/btn_bar_play" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_player_stop"
|
||||||
|
android:layout_width="25dp"
|
||||||
|
android:layout_height="25dp"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_noti_stop"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/ll_tab"
|
android:id="@+id/ll_tab"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
Loading…
Reference in New Issue