This commit is contained in:
ocean 2024-05-17 11:49:11 +08:00
parent 9b91074eeb
commit d14b11fac6
39 changed files with 994 additions and 548 deletions

View File

@ -119,9 +119,6 @@ class MainActivity : BaseActivity() {
intent.putExtra(PlayDetailsActivity.KEY_DETAILS_AUDIO, audio)
startActivity(intent)
}
binding.alarmClockBtn.setOnClickListener {
}
binding.playBlackBtn.setOnClickListener {
val currentPlayer = MediaControllerManager.getController()

View File

@ -6,20 +6,29 @@ import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.media3.common.Player
import androidx.media3.session.MediaController
import com.bumptech.glide.Glide
import com.player.musicoo.R
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.innertube.Innertube.TAG
import com.player.musicoo.media.MediaControllerManager
import com.player.musicoo.sp.AppStore
import com.player.musicoo.util.LogTag
import com.player.musicoo.view.MusicPlayerView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
@ -31,11 +40,13 @@ import java.io.IOException
import java.io.InputStream
abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope() {
private var playerListener: Player.Listener? = null
enum class Event {
ActivityStart,
ActivityStop,
ActivityOnResume
ActivityOnResume,
AutomaticallySwitchSongs,
}
protected val TAG = LogTag.VO_ACT_LOG
@ -45,6 +56,7 @@ abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope
protected abstract suspend fun main()
private var defer: suspend () -> Unit = {}
private var deferRunning = false
private lateinit var musicPlayerView: MusicPlayerView
fun defer(operation: suspend () -> Unit) {
this.defer = operation
@ -52,6 +64,8 @@ abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
musicPlayerView = MusicPlayerView(this, meController)
initPlayerListener()
launch {
main()
}
@ -90,21 +104,97 @@ abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope
}
}
suspend fun loadBitmapWithGlide(imageUrl: String): Bitmap? {
return withContext(Dispatchers.IO) {
try {
Glide.with(this@MoBaseActivity)
.asBitmap()
.load(imageUrl)
.submit() // 异步加载Bitmap
.get() // 阻塞等待获取Bitmap
} catch (e: Exception) {
e.printStackTrace()
null
fun addMusicPlayerViewToLayout(layoutId: LinearLayout) {
if (meController != null && meController.mediaItemCount > 0 && meController.duration > 0) {
if (layoutId.childCount <= 0) {//没有添加view才进行添加
layoutId.addView(musicPlayerView)
}
musicPlayerView.updateInfoUi(meController.currentMediaItem)
musicPlayerView.updateSetProgress(meController)
musicPlayerView.updateProgressState(meController)
layoutId.visibility = View.VISIBLE
} else {
layoutId.visibility = View.GONE
}
}
private fun initPlayerListener() {
if (this !is MoPlayDetailsActivity) {
if (playerListener == null) {
LogTag.LogD(TAG, "MoBaseActivity initPlayerListener")
meController?.addListener(getPlayerListener())
}
}
}
override fun onDestroy() {
super.onDestroy()
LogTag.LogD(TAG, "MoBaseActivity onDestroy")
if (meController != null && playerListener != null) {
meController.removeListener(playerListener!!)
}
}
private fun getPlayerListener(): Player.Listener {
if (playerListener == null) {
playerListener = object : Player.Listener {
override fun onPositionDiscontinuity(
oldPosition: Player.PositionInfo,
newPosition: Player.PositionInfo,
reason: Int
) {
if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) {
LogTag.LogD(
Innertube.TAG,
"MoBaseActivity DISCONTINUITY_REASON_AUTO_TRANSITION"
)
if (meController != null) {
musicPlayerView.updateInfoUi(meController.currentMediaItem)
musicPlayerView.updateSetProgress(meController)
musicPlayerView.updateProgressState(meController)
}
events.trySend(Event.AutomaticallySwitchSongs)
}
}
override fun onPlaybackStateChanged(playbackState: Int) {
LogTag.LogD(Innertube.TAG, "MoBaseActivity playbackState->$playbackState")
val meController = MediaControllerManager.getController()
if (meController != null) {
musicPlayerView.updateProgressState(meController)
when (playbackState) {
Player.STATE_READY -> {
musicPlayerView.updateSetProgress(meController)
}
else -> {}
}
}
}
override fun onPlayWhenReadyChanged(
playWhenReady: Boolean,
reason: Int
) {
LogTag.LogD(
Innertube.TAG,
"MoBaseActivity onPlayWhenReadyChanged->$playWhenReady"
)
musicPlayerView.updatePlayState(playWhenReady)
val meController = MediaControllerManager.getController()
if (meController != null) {
musicPlayerView.updateProgressState(meController)
}
}
}
}
return playerListener!!
}
fun applyGaussianBlur(inputBitmap: Bitmap, radius: Float, context: Context): Bitmap {
val rsContext = RenderScript.create(context)
val outputBitmap =
@ -120,16 +210,6 @@ abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope
return outputBitmap
}
fun loadBitmapFromAsset(id: Int): Bitmap {
return try {
val inputStream: InputStream = resources.openRawResource(id)
BitmapFactory.decodeStream(inputStream)
} catch (e: IOException) {
e.printStackTrace()
throw RuntimeException("Could not load bitmap from asset")
}
}
fun showSongDescriptionDialog(description: String) {
val inflater = LayoutInflater.from(this)
val dialogView = inflater.inflate(R.layout.dialog_description, null)

View File

@ -1,12 +1,12 @@
package com.player.musicoo.activity
import android.annotation.SuppressLint
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.bumptech.glide.Glide
import com.gyf.immersionbar.ktx.immersionBar
import com.player.musicoo.adapter.DetailsListAdapter
import com.player.musicoo.databinding.ActivityDetailsBinding
import com.player.musicoo.fragment.MoHomeFragment
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.innertube.requests.moPlaylistPage
import com.player.musicoo.util.LogTag.LogD
@ -28,6 +28,7 @@ class MoListDetailsActivity : MoBaseActivity() {
private lateinit var binding: ActivityDetailsBinding
private var browseId: String? = null
private var adapter: DetailsListAdapter? = null
override suspend fun main() {
binding = ActivityDetailsBinding.inflate(layoutInflater)
setContentView(binding.root)
@ -50,6 +51,7 @@ class MoListDetailsActivity : MoBaseActivity() {
}
}
@SuppressLint("NotifyDataSetChanged")
private suspend fun onReceive() {
while (isActive) {
select<Unit> {
@ -60,10 +62,34 @@ class MoListDetailsActivity : MoBaseActivity() {
}
}
}
events.onReceive {
when (it) {
Event.ActivityOnResume -> {
activityOnResume()
}
Event.AutomaticallySwitchSongs -> {
if (adapter != null) {
adapter?.notifyDataSetChanged()
}
}
else -> {}
}
}
}
}
}
@SuppressLint("NotifyDataSetChanged")
private fun activityOnResume() {
addMusicPlayerViewToLayout(binding.playMusicLayout)
if (adapter != null) {
adapter?.notifyDataSetChanged()
}
}
private fun initView() {
binding.backBtn.setOnClickListener {
finish()
@ -86,7 +112,7 @@ class MoListDetailsActivity : MoBaseActivity() {
binding.subtitle.text = it.subtitle
binding.secondSubtitle.text = it.secondSubtitle
val adapter = DetailsListAdapter(this, it.moPlaylistOrAlbumListBean)
adapter = DetailsListAdapter(this, it.moPlaylistOrAlbumListBean)
binding.rv.layoutManager =
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
binding.rv.adapter = adapter

View File

@ -24,7 +24,9 @@ import com.player.musicoo.databinding.ActivityMoPlayDetailsBinding
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.media.MediaControllerManager
import com.player.musicoo.media.SongRadio
import com.player.musicoo.sp.AppStore
import com.player.musicoo.util.LogTag.LogD
import com.player.musicoo.util.PlayMode
import com.player.musicoo.util.asMediaItem
import com.player.musicoo.util.convertMillisToMinutesAndSecondsString
import kotlinx.coroutines.Dispatchers
@ -65,7 +67,8 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
initImmersionBar()
initClick()
initPlayerListener()
initPlayListAdapter()
updatePlayModeUi()
val videoId = intent.getStringExtra(PLAY_DETAILS_VIDEO_ID)
val playlistId = intent.getStringExtra(PLAY_DETAILS_PLAY_LIST_ID)
val playlistSetVideoId = intent.getStringExtra(PLAY_DETAILS_PLAY_LIST_SET_VIDEO_ID)
@ -79,6 +82,7 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
if (meController != null && meController.currentMediaItem != null && videoId == meController.currentMediaItem?.mediaId) {
//进入的id与当前的id一样就不重新去获取播放
updateCurrentMediaItemInfo()
updateInfoUi(meController.currentMediaItem)
} else {
binding.nameTv.text = intent.getStringExtra(PLAY_DETAILS_NAME)
binding.descTv.text = intent.getStringExtra(PLAY_DETAILS_DESC)
@ -154,27 +158,42 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
binding.progressBar.progress = MediaControllerManager.getBufferedPosition().toInt()
binding.progressBar.max = MediaControllerManager.getDuration().toInt()
updateProgressBufferingState()
updatePlayListDataAndAdapter()
}
}
@SuppressLint("NotifyDataSetChanged")
private fun updatePlayListDataAndAdapter() {
if (meController != null && meController.currentMediaItem != null) {
val mediaItemCount = meController.mediaItemCount
val allMediaItems: MutableList<MediaItem> = mutableListOf()
for (index in 0 until mediaItemCount) {
val mediaItemAt = meController.getMediaItemAt(index)
allMediaItems.add(mediaItemAt)
}
playListAdapter = PlayListAdapter(
this@MoPlayDetailsActivity,
allMediaItems
)
binding.playListRv.layoutManager =
LinearLayoutManager(
this@MoPlayDetailsActivity,
LinearLayoutManager.VERTICAL,
false
)
binding.playListRv.adapter = playListAdapter
playList.clear()
playList.addAll(allMediaItems)
playListAdapter?.notifyDataSetChanged()
}
}
private var playList: MutableList<MediaItem> = mutableListOf()
private fun initPlayListAdapter() {
playListAdapter = PlayListAdapter(
this@MoPlayDetailsActivity,
playList
)
binding.playListRv.layoutManager =
LinearLayoutManager(
this@MoPlayDetailsActivity,
LinearLayoutManager.VERTICAL,
false
)
binding.playListRv.adapter = playListAdapter
}
@SuppressLint("NotifyDataSetChanged")
private fun initClick() {
binding.backBtn.setOnClickListener {
finish()
@ -189,6 +208,40 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
}
}
}
binding.playModeBtn.setOnClickListener {
if (meController != null) {
val playModeCounter = (appStore.playMusicMode + 1) % 3
appStore.playMusicMode = when (playModeCounter) {
0 -> PlayMode.LIST_LOOP.value
1 -> PlayMode.SINGLE_LOOP.value
else -> PlayMode.RANDOM.value
}
when (AppStore(this).playMusicMode) {
PlayMode.LIST_LOOP.value -> {
meController.repeatMode = Player.REPEAT_MODE_ALL
meController.shuffleModeEnabled = false
}
PlayMode.SINGLE_LOOP.value -> {
meController.repeatMode = Player.REPEAT_MODE_ONE
meController.shuffleModeEnabled = false
}
PlayMode.RANDOM.value -> {
meController.repeatMode = Player.REPEAT_MODE_ALL
// val availableCommands = meController.availableCommands
// //控制器支持设置随机播放模式的命令
// if (availableCommands.contains(Player.COMMAND_SET_SHUFFLE_MODE)) {
// meController.shuffleModeEnabled = true
// }
meController.shuffleModeEnabled = true
}
}
updatePlayModeUi()
LogD(TAG, "repeatMode->${meController.repeatMode}")
LogD(TAG, "shuffleModeEnabled->${meController.shuffleModeEnabled}")
}
}
binding.playLayoutBtn.setOnClickListener {
if (meController != null) {
if (meController.isPlaying) {
@ -249,6 +302,30 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
}
}
private fun updatePlayModeUi() {
binding.modePlayImg.setImageResource(
when (AppStore(this).playMusicMode) {
PlayMode.LIST_LOOP.value -> {
R.drawable.mode_cycle_play_icon
}
PlayMode.SINGLE_LOOP.value -> {
R.drawable.mode_single_play_icon
}
PlayMode.RANDOM.value -> {
R.drawable.mode_random_play_icon
}
else -> {
R.drawable.mode_cycle_play_icon
}
}
)
}
@SuppressLint("NotifyDataSetChanged")
private fun initData(
videoId: String,
playlistId: String? = null,
@ -268,18 +345,6 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
binding.loadingView.visibility = View.GONE
binding.disableClicksLayout.visibility = View.GONE
binding.playbackErrorLayout.visibility = View.VISIBLE
} else {
playListAdapter = PlayListAdapter(
this@MoPlayDetailsActivity,
songRadioList.map(Innertube.SongItem::asMediaItem)
)
binding.playListRv.layoutManager =
LinearLayoutManager(
this@MoPlayDetailsActivity,
LinearLayoutManager.VERTICAL,
false
)
binding.playListRv.adapter = playListAdapter
}
if (isFinishing) {
@ -322,6 +387,8 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
.filter { filter -> filter.mediaId != videoId }
it.addMediaItems(mediaItems)
}
updatePlayListDataAndAdapter()
} else {
binding.playbackErrorLayout.visibility = View.VISIBLE
}

View File

@ -91,10 +91,24 @@ class MoSearchMoreActivity : MoBaseActivity() {
}
}
}
events.onReceive {
when (it) {
Event.ActivityOnResume -> {
activityOnResume()
}
else -> {}
}
}
}
}
}
private fun activityOnResume() {
addMusicPlayerViewToLayout(binding.playMusicLayout)
}
private fun initView() {
binding.backBtn.setOnClickListener {
finish()

View File

@ -59,10 +59,23 @@ class MoSingerDetailsActivity : MoBaseActivity() {
}
}
}
events.onReceive {
when (it) {
Event.ActivityOnResume -> {
activityOnResume()
}
else -> {}
}
}
}
}
}
private fun activityOnResume() {
addMusicPlayerViewToLayout(binding.playMusicLayout)
}
private fun initView() {
binding.backBtn.setOnClickListener {
finish()

View File

@ -74,16 +74,29 @@ class MoSingerMoreSongActivity : MoBaseActivity() {
Request.MoreData -> {
if (!currentContinuation.isNullOrEmpty()) {
initDataMore(currentContinuation!!)
}else{
} else {
binding.refreshLayout.finishLoadMoreWithNoMoreData()
}
}
}
}
events.onReceive {
when (it) {
Event.ActivityOnResume -> {
activityOnResume()
}
else -> {}
}
}
}
}
}
private fun activityOnResume() {
addMusicPlayerViewToLayout(binding.playMusicLayout)
}
private fun initView() {
binding.backBtn.setOnClickListener {
finish()

View File

@ -15,13 +15,14 @@ import com.player.musicoo.R
import com.player.musicoo.databinding.ActivityPrimaryBinding
import com.player.musicoo.fragment.ImportFragment
import com.player.musicoo.fragment.MoHomeFragment
import com.player.musicoo.fragment.MoMeFragment
import com.player.musicoo.fragment.SearchFragment
import com.player.musicoo.media.MediaControllerManager
import com.player.musicoo.util.LogTag.LogD
import kotlinx.coroutines.isActive
import kotlinx.coroutines.selects.select
class PrimaryActivity : MoBaseActivity() ,SearchFragment.SearchFragmentCancelClickListener{
class PrimaryActivity : MoBaseActivity(), SearchFragment.SearchFragmentCancelClickListener {
/**
* musicResponsiveListItemRenderer
* musicTwoRowItemRenderer
@ -36,8 +37,6 @@ class PrimaryActivity : MoBaseActivity() ,SearchFragment.SearchFragmentCancelCli
binding = ActivityPrimaryBinding.inflate(layoutInflater)
setContentView(binding.root)
initView()
initPlayerListener()
onReceive()
}
@ -55,32 +54,10 @@ class PrimaryActivity : MoBaseActivity() ,SearchFragment.SearchFragmentCancelCli
updateBtnState(1)
changeFragment(1)
}
binding.importBtn.setOnClickListener {
binding.meBtn.setOnClickListener {
updateBtnState(2)
changeFragment(2)
}
binding.playBlackBtn.setOnClickListener {
if (meController != null) {
if (meController.isPlaying) {
meController.pause()
updatePlayState(false)
} else {
meController.play()
updatePlayState(true)
}
updateProgressState()
}
}
binding.goDetailsBtn.setOnClickListener {
val intent = Intent(this, MoPlayDetailsActivity::class.java)
intent.putExtra(
MoPlayDetailsActivity.PLAY_DETAILS_COME_FROM,
PrimaryActivity::class.java
)
startActivity(intent)
}
}
private fun initFragment() {
@ -89,7 +66,7 @@ class PrimaryActivity : MoBaseActivity() ,SearchFragment.SearchFragmentCancelCli
val searchFragment = SearchFragment()
searchFragment.setButtonClickListener(this)
mFragments.add(searchFragment)
mFragments.add(ImportFragment())
mFragments.add(MoMeFragment())
updateBtnState(0)
changeFragment(0)
}
@ -137,10 +114,10 @@ class PrimaryActivity : MoBaseActivity() ,SearchFragment.SearchFragmentCancelCli
}
}
)
importImg.setImageResource(
meImg.setImageResource(
when (index) {
2 -> R.drawable.import_select_icon
else -> R.drawable.import_unselect_icon
2 -> R.drawable.me_select_icon
else -> R.drawable.me_unselect_icon
}
)
}
@ -164,60 +141,13 @@ class PrimaryActivity : MoBaseActivity() ,SearchFragment.SearchFragmentCancelCli
}
private fun activityOnResume() {
if (meController != null && meController.mediaItemCount > 0 && meController.duration > 0) {
binding.playingStatusLayout.visibility = View.VISIBLE
updateInfoUi(meController.currentMediaItem)
} else {
binding.playingStatusLayout.visibility = View.GONE
}
addMusicPlayerViewToLayout(binding.playMusicLayout)
}
private fun initPlayerListener() {
meController?.addListener(playerListener)
override fun onFragmentClick() {
onBackPressed()
}
private val playerListener = object : Player.Listener {
override fun onPositionDiscontinuity(
oldPosition: Player.PositionInfo,
newPosition: Player.PositionInfo,
reason: Int
) {
if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) {
updateInfoUi(meController?.currentMediaItem)
}
}
override fun onPlaybackStateChanged(playbackState: Int) {
LogD(TAG, "playbackState->$playbackState")
updateProgressState()
when (playbackState) {
Player.STATE_READY -> {
if (meController != null) {
LogD(TAG, "meController.duration->${meController.duration}")
binding.progressBar.setMaxProgress(MediaControllerManager.getDuration())
val currentPosition = meController.currentPosition
binding.progressBar.setProgress(currentPosition)
}
}
else -> {}
}
}
override fun onPlayWhenReadyChanged(
playWhenReady: Boolean,
reason: Int
) {
updatePlayState(playWhenReady)
updateProgressState()
}
}
override fun onDestroy() {
super.onDestroy()
meController?.removeListener(playerListener)
}
private var backPressedTime: Long = 0
private val backToast: Toast by lazy {
@ -239,56 +169,4 @@ class PrimaryActivity : MoBaseActivity() ,SearchFragment.SearchFragmentCancelCli
backPressedTime = System.currentTimeMillis()
}
}
/**
* 更新播放进度
*/
private fun updateProgressState() {
//判断是否ready与播放中否则停止更新进度
if (meController != null && meController.playbackState == Player.STATE_READY && meController.isPlaying) {
updatePlayState(meController.isPlaying)
progressHandler.removeCallbacksAndMessages(null)
progressHandler.sendEmptyMessage(1)
} else {
progressHandler.removeCallbacksAndMessages(null)
}
}
/**
* 播放进度
*/
private val progressHandler = object : Handler(Looper.myLooper()!!) {
override fun handleMessage(msg: Message) {
//判断是否ready与播放中否则停止更新进度
if (meController != null && meController.playbackState == Player.STATE_READY && meController.isPlaying) {
val currentPosition = meController.currentPosition
binding.progressBar.setProgress(currentPosition)
sendEmptyMessageDelayed(1, 50)
}
}
}
private fun updatePlayState(b: Boolean) {
if (b) {
binding.playStatusImg.setImageResource(R.drawable.playing_black_icon)
} else {
binding.playStatusImg.setImageResource(R.drawable.play_black_icon)
}
}
private fun updateInfoUi(mediaItem: MediaItem?) {
if (mediaItem == null) {
return
}
Glide.with(this@PrimaryActivity)
.load(mediaItem.mediaMetadata.artworkUri)
.into(binding.audioImg)
binding.name.text = mediaItem.mediaMetadata.title
binding.desc.text = mediaItem.mediaMetadata.artist
}
override fun onFragmentClick() {
onBackPressed()
}
}

View File

@ -19,6 +19,7 @@ import com.player.musicoo.databinding.SoundsOfAppliancesLayoutBinding
import com.player.musicoo.databinding.SoundsOfNatureLayoutBinding
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.innertube.models.MusicCarouselShelfRenderer
import com.player.musicoo.media.MediaControllerManager
import com.player.musicoo.util.convertMillisToMinutesAndSecondsString
import com.player.musicoo.util.getAudioDurationFromAssets
@ -28,10 +29,6 @@ class DetailsListAdapter(
) :
RecyclerView.Adapter<DetailsListAdapter.ViewHolder>() {
companion object {
const val FROM_TAG = "list_details_activity_to_adapter"
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = DetailsListItemBinding.inflate(LayoutInflater.from(context), parent, false)
return ViewHolder(binding)
@ -66,7 +63,6 @@ class DetailsListAdapter(
@SuppressLint("SetTextI18n")
fun bind(bean: Innertube.MoPlaylistOrAlbumPage.MoPlaylistOrAlbumListBean) {
binding.apply {
if (!bean.thumbnailUrl.isNullOrEmpty()) {
image.visibility = View.VISIBLE
@ -87,7 +83,16 @@ class DetailsListAdapter(
name.visibility = View.VISIBLE
name.text = bean.name
}
val meController = MediaControllerManager.getController()
if (meController != null && meController.currentMediaItem != null) {
if (meController.currentMediaItem?.mediaId == bean.videoId) {
binding.title.setTextColor(context.getColor(R.color.green))
binding.name.setTextColor(context.getColor(R.color.green_60))
} else {
binding.title.setTextColor(context.getColor(R.color.white))
binding.name.setTextColor(context.getColor(R.color.white_60))
}
}
}
}
}

View File

@ -54,19 +54,6 @@ class PlayListAdapter(
fun bind(bean: MediaItem) {
binding.apply {
val meController = MediaControllerManager.getController()
if (meController != null && meController.currentMediaItem != null) {
if (meController.currentMediaItem?.mediaId == bean.mediaId) {
binding.currentPlayingLayout.visibility = View.VISIBLE
binding.title.setTextColor(context.getColor(R.color.green))
binding.name.setTextColor(context.getColor(R.color.green_60))
} else {
binding.currentPlayingLayout.visibility = View.GONE
binding.title.setTextColor(context.getColor(R.color.white))
binding.name.setTextColor(context.getColor(R.color.white_60))
}
}
Glide.with(context)
.load(bean.mediaMetadata.artworkUri)
.into(image)
@ -77,7 +64,16 @@ class PlayListAdapter(
name.visibility = View.VISIBLE
name.text = bean.mediaMetadata.artist
}
val meController = MediaControllerManager.getController()
if (meController != null && meController.currentMediaItem != null) {
if (meController.currentMediaItem?.mediaId == bean.mediaId) {
binding.title.setTextColor(context.getColor(R.color.green))
binding.name.setTextColor(context.getColor(R.color.green_60))
} else {
binding.title.setTextColor(context.getColor(R.color.white))
binding.name.setTextColor(context.getColor(R.color.white_60))
}
}
}
}
}

View File

@ -62,7 +62,7 @@ class MoHomeFragment : MoBaseFragment<FragmentMoHomeBinding>() {
private suspend fun initData() {
showLoadingUi()
Innertube.homePage()?.onSuccess {
Innertube.homePage(appStore.myVisitorData)?.onSuccess {
showDataUi()
if (it.homePage.isNotEmpty()) {
for (home: Innertube.HomePage in it.homePage) {

View File

@ -0,0 +1,60 @@
package com.player.musicoo.fragment
import android.view.LayoutInflater
import android.view.ViewGroup
import com.gyf.immersionbar.ktx.immersionBar
import com.player.musicoo.databinding.FragmentMoHomeBinding
import com.player.musicoo.databinding.FragmentMoMeBinding
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.isActive
import kotlinx.coroutines.selects.select
class MoMeFragment : MoBaseFragment<FragmentMoMeBinding>() {
private val requests: Channel<Request> = Channel(Channel.UNLIMITED)
enum class Request {
}
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentMoMeBinding
get() = FragmentMoMeBinding::inflate
override suspend fun onViewCreated() {
initView()
onReceive()
}
private fun initImmersionBar() {
immersionBar {
statusBarDarkFont(false)
statusBarView(binding.view)
}
}
private suspend fun onReceive() {
while (isActive) {
select<Unit> {
requests.onReceive {
}
}
}
}
private fun initView() {
}
override fun onResume() {
super.onResume()
initImmersionBar()
}
override fun onHiddenChanged(hidden: Boolean) {
super.onHiddenChanged(hidden)
if (!hidden) {
initImmersionBar()
}
}
}

View File

@ -1,21 +1,34 @@
package com.player.musicoo.innertube.requests
import com.player.musicoo.App
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.innertube.models.BrowseResponse
import com.player.musicoo.innertube.models.Context
import com.player.musicoo.innertube.models.SectionListRenderer
import com.player.musicoo.innertube.models.bodies.BrowseBody
import com.player.musicoo.innertube.utils.runCatchingNonCancellable
import com.player.musicoo.sp.AppStore
import com.player.musicoo.util.LogTag
import io.ktor.client.call.body
import io.ktor.client.request.post
import io.ktor.client.request.setBody
//
suspend fun Innertube.homePage(): Result<Innertube.BaseHomePage>? =
suspend fun Innertube.homePage(visitorData: String? = null): Result<Innertube.BaseHomePage>? =
runCatchingNonCancellable {
LogTag.LogD(TAG, "visitorData->${visitorData}")
val defaultWeb = Context(
client = Context.Client(
clientName = "WEB_REMIX",
clientVersion = "1.20220918",
platform = "DESKTOP",
visitorData = visitorData
)
)
val response = client.post(browse) {
setBody(BrowseBody(Context.DefaultWeb, "FEmusic_home"))
setBody(BrowseBody(defaultWeb, "FEmusic_home"))
}.body<BrowseResponse>()
val sectionListRenderer = response
@ -29,7 +42,10 @@ suspend fun Innertube.homePage(): Result<Innertube.BaseHomePage>? =
val contents = sectionListRenderer?.contents
val visitorData = response.responseContext?.visitorData
val visitorDataNew= response.responseContext?.visitorData
// if(!visitorDataNew.isNullOrEmpty()){
// AppStore(App.app).myVisitorData = visitorDataNew
// }
val continuations = sectionListRenderer?.continuations
val nextContinuationData = continuations
@ -66,7 +82,7 @@ suspend fun Innertube.homePage(): Result<Innertube.BaseHomePage>? =
}
val baseHomePage =
Innertube.BaseHomePage(
visitorData,
visitorDataNew,
cToken,
cToken.toString(),
itct.toString(),

View File

@ -1,11 +1,13 @@
package com.player.musicoo.innertube.requests
import com.player.musicoo.App
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.innertube.models.BrowseResponse
import com.player.musicoo.innertube.models.Context
import com.player.musicoo.innertube.models.SectionListContinuation
import com.player.musicoo.innertube.models.bodies.BrowseMoreBody
import com.player.musicoo.innertube.utils.runCatchingNonCancellable
import com.player.musicoo.sp.AppStore
import io.ktor.client.call.body
import io.ktor.client.request.post
import io.ktor.client.request.setBody

View File

@ -1,10 +1,13 @@
package com.player.musicoo.innertube.requests
import com.player.musicoo.App
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.innertube.models.BrowseResponse
import com.player.musicoo.innertube.models.MusicShelfRenderer
import com.player.musicoo.innertube.models.bodies.BrowseBody
import com.player.musicoo.innertube.utils.runCatchingNonCancellable
import com.player.musicoo.sp.AppStore
import com.player.musicoo.util.LogTag
import io.ktor.client.call.body
import io.ktor.client.request.post
import io.ktor.client.request.setBody
@ -15,7 +18,6 @@ suspend fun Innertube.moPlaylistPage(browseId: String): Result<Innertube.MoPlayl
setBody(BrowseBody(browseId = browseId))
}.body<BrowseResponse>()
val musicDetailHeaderRenderer = response
.header
?.musicDetailHeaderRenderer

View File

@ -1,5 +1,6 @@
package com.player.musicoo.innertube.requests
import com.player.musicoo.App
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.innertube.models.BrowseResponse
import com.player.musicoo.innertube.models.ContinuationResponse
@ -10,6 +11,7 @@ import com.player.musicoo.innertube.models.SectionListRenderer
import com.player.musicoo.innertube.models.bodies.BrowseBody
import com.player.musicoo.innertube.models.bodies.ContinuationBody
import com.player.musicoo.innertube.utils.runCatchingNonCancellable
import com.player.musicoo.sp.AppStore
import com.player.musicoo.util.LogTag
import io.ktor.client.call.body
import io.ktor.client.request.post

View File

@ -39,9 +39,11 @@ import com.player.musicoo.R
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.innertube.models.bodies.PlayerBody
import com.player.musicoo.innertube.requests.player
import com.player.musicoo.sp.AppStore
import com.player.musicoo.util.ExoPlayerDiskCacheMaxSize
import com.player.musicoo.util.LogTag
import com.player.musicoo.util.LogTag.LogD
import com.player.musicoo.util.PlayMode
import com.player.musicoo.util.RingBuffer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
@ -90,6 +92,22 @@ class PlaybackService : MediaSessionService(), Player.Listener {
)
.setUsePlatformDiagnostics(false)
.build()
when (AppStore(this).playMusicMode) {
PlayMode.LIST_LOOP.value -> {
player.repeatMode = Player.REPEAT_MODE_ALL
player.shuffleModeEnabled = false
}
PlayMode.SINGLE_LOOP.value -> {
player.repeatMode = Player.REPEAT_MODE_ONE
player.shuffleModeEnabled = false
}
PlayMode.RANDOM.value -> {
player.repeatMode = Player.REPEAT_MODE_ALL
player.shuffleModeEnabled = true
}
}
player.repeatMode = Player.REPEAT_MODE_ALL
player.addListener(this)

View File

@ -3,6 +3,7 @@ package com.player.musicoo.sp
import android.content.Context
import com.player.musicoo.sp.store.Store
import com.player.musicoo.sp.store.asStoreProvider
import com.player.musicoo.util.PlayMode
class AppStore(context: Context) {
private val store = Store(
@ -16,8 +17,20 @@ class AppStore(context: Context) {
defaultValue = emptySet()
)
var myVisitorData: String by store.string(
key = MY_VISITOR_DATA,
defaultValue = ""
)
var playMusicMode: Int by store.int(
key = PLAY_MUSIC_MODE,
defaultValue = PlayMode.LIST_LOOP.value
)
companion object {
private const val FILE_NAME = "music_oo_app"
const val SEARCH_HISTORY = "search_history"
const val MY_VISITOR_DATA = "my_visitor_data"
const val PLAY_MUSIC_MODE = "play_music_mode"
}
}

View File

@ -0,0 +1,11 @@
package com.player.musicoo.util
enum class PlayMode(val value: Int) {
LIST_LOOP(0), // 列表循环
SINGLE_LOOP(1), // 单曲循环
RANDOM(2); // 随机播放
companion object {
fun fromValue(value: Int) = entries.firstOrNull { it.value == value } ?: LIST_LOOP
}
}

View File

@ -0,0 +1,126 @@
package com.player.musicoo.view
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.session.MediaController
import com.bumptech.glide.Glide
import com.player.musicoo.R
import com.player.musicoo.activity.MoPlayDetailsActivity
import com.player.musicoo.activity.PrimaryActivity
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.media.MediaControllerManager
import com.player.musicoo.util.LogTag
@SuppressLint("ViewConstructor")
class MusicPlayerView(
val context: Activity,
val meController: MediaController?,
attrs: AttributeSet? = null
) :
LinearLayout(context, attrs) {
private var goDetailsBtn: LinearLayout
private var progressBar: CircularProgressBar
private var playStatusImg: ImageView
private var audioImg: ImageView
private var name: TextView
private var desc: TextView
private var playBlackBtn: LinearLayout
init {
LayoutInflater.from(context).inflate(R.layout.music_player_layout, this, true)
goDetailsBtn = findViewById(R.id.goDetailsBtn)
progressBar = findViewById(R.id.progressBar)
playStatusImg = findViewById(R.id.play_status_img)
audioImg = findViewById(R.id.audio_img)
name = findViewById(R.id.name)
desc = findViewById(R.id.desc)
playBlackBtn = findViewById(R.id.play_black_btn)
initOnClickListener()
}
private fun initOnClickListener() {
playBlackBtn.setOnClickListener {
if (meController != null) {
if (meController.isPlaying) {
meController.pause()
updatePlayState(false)
} else {
meController.play()
updatePlayState(true)
}
updateProgressState(meController)
}
}
goDetailsBtn.setOnClickListener {
val intent = Intent(context, MoPlayDetailsActivity::class.java)
intent.putExtra(
MoPlayDetailsActivity.PLAY_DETAILS_COME_FROM,
PrimaryActivity::class.java
)
context.startActivity(intent)
}
}
fun updateProgressState(meController: MediaController) {
//判断是否ready与播放中否则停止更新进度
if (meController.playbackState == Player.STATE_READY && meController.isPlaying) {
updatePlayState(meController.isPlaying)
progressHandler.removeCallbacksAndMessages(null)
progressHandler.sendEmptyMessage(1)
} else {
progressHandler.removeCallbacksAndMessages(null)
}
}
/**
* 播放进度
*/
private val progressHandler = object : Handler(Looper.myLooper()!!) {
override fun handleMessage(msg: Message) {
//判断是否ready与播放中否则停止更新进度
if (meController != null && meController.playbackState == Player.STATE_READY && meController.isPlaying) {
val currentPosition = meController.currentPosition
progressBar.setProgress(currentPosition)
sendEmptyMessageDelayed(1, 50)
}
}
}
fun updatePlayState(b: Boolean) {
if (b) {
playStatusImg.setImageResource(R.drawable.playing_black_icon)
} else {
playStatusImg.setImageResource(R.drawable.play_black_icon)
}
}
fun updateInfoUi(mediaItem: MediaItem?) {
if (mediaItem == null) {
return
}
Glide.with(context)
.load(mediaItem.mediaMetadata.artworkUri)
.into(audioImg)
name.text = mediaItem.mediaMetadata.title
desc.text = mediaItem.mediaMetadata.artist
}
fun updateSetProgress(meController: MediaController) {
progressBar.setMaxProgress(MediaControllerManager.getDuration())
val currentPosition = meController.currentPosition
progressBar.setProgress(currentPosition)
}
}

View File

@ -1,33 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="34dp"
android:height="34dp"
android:viewportWidth="34"
android:viewportHeight="34">
<path
android:pathData="M17,31.403C24.172,31.403 29.986,25.589 29.986,18.417C29.986,11.245 24.172,5.43 17,5.43C9.828,5.43 4.014,11.245 4.014,18.417C4.014,25.589 9.828,31.403 17,31.403Z"
android:strokeLineJoin="round"
android:strokeWidth="1.66667"
android:fillColor="#333333"
android:strokeColor="#333333"/>
<path
android:pathData="M16.83,10.875L16.829,18.673L22.334,24.179"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#ffffff"
android:strokeLineCap="round"/>
<path
android:pathData="M2.833,6.375L7.792,2.833"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#333333"
android:strokeLineCap="round"/>
<path
android:pathData="M31.167,6.375L26.208,2.833"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#333333"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="36dp"
android:height="36dp"
android:viewportWidth="36"
android:viewportHeight="36">
<path
android:strokeWidth="1"
android:pathData="M18,18m-17.5,0a17.5,17.5 0,1 1,35 0a17.5,17.5 0,1 1,-35 0"
android:fillColor="#00000000"
android:strokeColor="#80F988"/>
<path
android:pathData="M22.445,22.593C24.09,21.548 25.351,19.998 26.039,18.176C26.728,16.354 26.806,14.357 26.262,12.486C25.719,10.615 24.582,8.972 23.024,7.802C21.466,6.632 19.571,6 17.623,6C15.675,6 13.779,6.632 12.221,7.802C10.663,8.972 9.527,10.615 8.983,12.486C8.44,14.357 8.518,16.354 9.206,18.176C9.894,19.998 11.156,21.548 12.8,22.593C11.519,23.199 10.419,24.131 9.612,25.297C8.804,26.462 8.317,27.819 8.2,29.232C8.195,29.43 8.269,29.622 8.405,29.766C8.541,29.91 8.728,29.994 8.926,30H26.362C26.46,29.998 26.557,29.976 26.647,29.936C26.738,29.896 26.819,29.839 26.887,29.768C26.955,29.696 27.008,29.612 27.044,29.521C27.079,29.429 27.096,29.331 27.094,29.232C26.973,27.814 26.479,26.453 25.663,25.287C24.847,24.121 23.737,23.191 22.445,22.593ZM21.749,19.132C21.231,19.715 20.601,20.189 19.896,20.525C19.192,20.861 18.427,21.052 17.647,21.087H17.443C15.913,20.956 14.492,20.243 13.472,19.096C13.405,19.019 13.354,18.929 13.322,18.833C13.29,18.736 13.277,18.633 13.285,18.532C13.294,18.43 13.322,18.331 13.369,18.24C13.416,18.15 13.48,18.069 13.559,18.004C13.637,17.939 13.728,17.89 13.826,17.86C13.923,17.831 14.026,17.821 14.127,17.832C14.229,17.842 14.327,17.873 14.417,17.922C14.506,17.971 14.585,18.038 14.648,18.118C15.403,18.949 16.439,19.471 17.557,19.581C18.631,19.635 19.704,19.114 20.748,18.076C20.889,17.942 21.077,17.869 21.271,17.872C21.466,17.875 21.651,17.953 21.789,18.091C21.926,18.228 22.005,18.414 22.007,18.608C22.01,18.802 21.937,18.99 21.803,19.132H21.749Z"
android:fillColor="#80F988"/>
</vector>

View File

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="36dp"
android:height="36dp"
android:viewportWidth="36"
android:viewportHeight="36">
<path
android:fillColor="#00000000"
android:pathData="M18,18m-17.5,0a17.5,17.5 0,1 1,35 0a17.5,17.5 0,1 1,-35 0"
android:strokeWidth="1"
android:strokeColor="#9C9D9D" />
<path
android:fillColor="#9C9D9D"
android:fillType="evenOdd"
android:pathData="M22.445,22.593C24.09,21.548 25.351,19.998 26.039,18.176C26.728,16.354 26.806,14.357 26.262,12.486C25.719,10.615 24.582,8.972 23.024,7.802C21.466,6.632 19.571,6 17.623,6C15.675,6 13.779,6.632 12.221,7.802C10.663,8.972 9.527,10.615 8.983,12.486C8.44,14.357 8.518,16.354 9.206,18.176C9.894,19.998 11.156,21.548 12.8,22.593C11.519,23.199 10.419,24.131 9.612,25.297C8.804,26.462 8.317,27.819 8.2,29.232C8.195,29.43 8.269,29.622 8.405,29.766C8.541,29.91 8.728,29.994 8.926,30H26.362C26.46,29.998 26.557,29.976 26.647,29.936C26.738,29.896 26.819,29.839 26.887,29.768C26.955,29.696 27.008,29.612 27.044,29.521C27.079,29.429 27.096,29.331 27.094,29.232C26.973,27.814 26.479,26.453 25.663,25.287C24.847,24.121 23.737,23.191 22.445,22.593ZM21.749,19.132C21.231,19.715 20.601,20.189 19.896,20.525C19.192,20.861 18.427,21.052 17.647,21.087H17.443C15.913,20.956 14.492,20.243 13.472,19.096C13.405,19.019 13.354,18.929 13.322,18.833C13.29,18.736 13.277,18.633 13.285,18.532C13.294,18.43 13.322,18.331 13.369,18.24C13.416,18.15 13.48,18.069 13.559,18.004C13.637,17.939 13.728,17.89 13.826,17.86C13.923,17.831 14.026,17.821 14.127,17.832C14.229,17.842 14.327,17.873 14.417,17.922C14.506,17.971 14.585,18.038 14.648,18.118C15.403,18.949 16.439,19.471 17.557,19.581C18.631,19.635 19.704,19.114 20.748,18.076C20.889,17.942 21.077,17.869 21.271,17.872C21.466,17.875 21.651,17.953 21.789,18.091C21.926,18.228 22.005,18.414 22.007,18.608C22.01,18.802 21.937,18.99 21.803,19.132H21.749Z" />
</vector>

View File

@ -0,0 +1,32 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#00000000"
android:pathData="M20,16.5L22,18.5L20,20.5"
android:strokeWidth="1.5"
android:strokeColor="#ffffff"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
<path
android:fillColor="#00000000"
android:pathData="M20,3.5L22,5.5L20,7.5"
android:strokeWidth="1.5"
android:strokeColor="#ffffff"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
<path
android:fillColor="#00000000"
android:pathData="M22,5.5H18.5C14.91,5.5 12,8.41 12,12C12,15.59 14.91,18.5 18.5,18.5H22"
android:strokeWidth="1.5"
android:strokeColor="#ffffff"
android:strokeLineCap="round" />
<path
android:fillColor="#00000000"
android:pathData="M2,18.5H5.5C9.09,18.5 12,15.59 12,12C12,8.41 9.09,5.5 5.5,5.5H2"
android:strokeWidth="1.5"
android:strokeColor="#ffffff"
android:strokeLineCap="round" />
</vector>

View File

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<clip-path android:pathData="M0,0h24v24h-24z" />
<path
android:fillColor="#ffffff"
android:pathData="M21.806,6.569C23.229,8.017 24.021,9.97 24.011,12C24.014,12.695 23.92,13.386 23.734,14.055C23.673,14.267 23.53,14.446 23.338,14.553C23.145,14.66 22.918,14.686 22.706,14.625C22.492,14.566 22.31,14.425 22.198,14.233C22.086,14.041 22.053,13.814 22.106,13.598C22.243,13.076 22.313,12.539 22.316,12C22.33,10.443 21.727,8.943 20.639,7.828C19.552,6.714 18.067,6.075 16.51,6.051H8.603V7.589C8.603,8.077 8.265,8.272 7.853,8.009L4.237,5.759C4.146,5.717 4.069,5.649 4.016,5.565C3.962,5.481 3.933,5.382 3.933,5.282C3.933,5.182 3.962,5.084 4.016,5C4.069,4.915 4.146,4.848 4.237,4.806L7.86,2.368C8.265,2.105 8.611,2.285 8.611,2.781V4.318H16.51C17.501,4.319 18.481,4.518 19.394,4.905C20.306,5.291 21.131,5.857 21.821,6.569H21.806ZM20.41,18.279C20.501,18.321 20.578,18.388 20.632,18.473C20.686,18.557 20.715,18.655 20.715,18.755C20.715,18.855 20.686,18.953 20.632,19.038C20.578,19.122 20.501,19.189 20.41,19.232L16.78,21.632C16.375,21.895 16.03,21.715 16.03,21.219V19.682H7.508C6.517,19.681 5.536,19.482 4.624,19.095C3.711,18.709 2.886,18.143 2.197,17.431C0.98,16.174 0.221,14.545 0.041,12.805C-0.138,11.065 0.272,9.315 1.207,7.837C1.265,7.742 1.343,7.659 1.434,7.595C1.525,7.53 1.628,7.485 1.738,7.461C1.847,7.437 1.96,7.435 2.069,7.456C2.179,7.477 2.284,7.52 2.377,7.582C2.567,7.707 2.701,7.903 2.748,8.126C2.796,8.349 2.754,8.582 2.632,8.774C2.023,9.74 1.701,10.858 1.702,12C1.688,13.557 2.29,15.057 3.378,16.172C4.466,17.286 5.951,17.925 7.508,17.949H16.052V16.411C16.052,15.923 16.382,15.728 16.802,15.991L20.418,18.279H20.41Z" />
<path
android:fillColor="#ffffff"
android:pathData="M13.064,16.192C13.064,16.64 12.704,17 12.256,17C11.808,17 11.448,16.64 11.448,16.192V10.256L10.68,10.504C10.68,10.504 10.68,10.504 10.672,10.504C10.664,10.504 10.656,10.512 10.648,10.512C10.632,10.512 10.616,10.52 10.6,10.52C10.592,10.528 10.584,10.528 10.576,10.528C10.56,10.528 10.544,10.536 10.52,10.536C10.52,10.536 10.512,10.536 10.504,10.536C10.48,10.544 10.456,10.544 10.424,10.544C9.976,10.544 9.616,10.176 9.616,9.728C9.616,9.368 9.856,9.064 10.176,8.96H10.184C10.184,8.96 10.184,8.96 10.192,8.96L11.96,8.384C11.96,8.384 11.952,8.384 11.944,8.384C11.96,8.384 11.968,8.376 11.984,8.376L11.96,8.384C11.976,8.376 11.992,8.368 12.008,8.368L12.016,8.36C12.04,8.352 12.064,8.352 12.088,8.344C12.096,8.344 12.104,8.344 12.104,8.344C12.128,8.336 12.144,8.336 12.16,8.328C12.144,8.336 12.128,8.336 12.112,8.336C12.128,8.336 12.144,8.336 12.16,8.328H12.168C12.176,8.328 12.176,8.328 12.184,8.328C12.2,8.328 12.208,8.328 12.216,8.328C12.208,8.328 12.2,8.328 12.192,8.328C12.208,8.328 12.232,8.328 12.256,8.328C12.704,8.328 13.064,8.688 13.064,9.136V16.192ZM11.864,8.424C11.824,8.448 11.784,8.48 11.744,8.504C11.784,8.48 11.824,8.448 11.864,8.424ZM11.68,8.568C11.664,8.584 11.648,8.6 11.64,8.616C11.648,8.6 11.664,8.584 11.68,8.568ZM11.448,9.064C11.448,9.088 11.448,9.112 11.448,9.136C11.448,9.112 11.448,9.088 11.448,9.064ZM11.632,8.624C11.616,8.64 11.6,8.664 11.584,8.68C11.6,8.664 11.616,8.64 11.632,8.624ZM11.504,8.824C11.496,8.848 11.488,8.872 11.48,8.896C11.488,8.872 11.496,8.848 11.504,8.824Z" />
</group>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11.12,20.72C5.84,20.72 1.52,16.4 1.52,11.12C1.52,5.84 5.84,1.52 11.12,1.52C16.399,1.52 20.719,5.84 20.719,11.12C20.719,16.4 16.399,20.72 11.12,20.72ZM11.12,19.12C15.519,19.12 19.119,15.52 19.119,11.12C19.119,6.72 15.519,3.12 11.12,3.12C6.72,3.12 3.12,6.72 3.12,11.12C3.12,15.52 6.72,19.12 11.12,19.12ZM17.039,20.4C16.719,20.08 16.799,19.52 17.119,19.28C17.44,19.04 18,19.04 18.24,19.36L19.76,21.2C20.08,21.52 20,22.08 19.68,22.32C19.36,22.56 18.799,22.56 18.559,22.24L17.039,20.4Z"
android:fillColor="#ffffff"
android:fillAlpha="0.85"/>
</vector>

View File

@ -1,19 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:viewportWidth="28"
android:viewportHeight="28">
<group>
<clip-path
android:pathData="M28,0l-28,0l-0,28l28,0z"/>
android:width="36dp"
android:height="36dp"
android:viewportWidth="36"
android:viewportHeight="36">
<path
android:pathData="M13.5,2C7.149,2 2,7.149 2,13.5C2,19.851 7.149,25 13.5,25C19.851,25 25,19.851 25,13.5C25,7.149 19.851,2 13.5,2ZM11.354,6.861C11.819,6.795 12.176,6.395 12.176,5.912C12.176,5.383 11.747,4.954 11.218,4.954C11.16,4.954 11.104,4.959 11.049,4.968C7.923,5.472 5.472,7.923 4.968,11.049C4.959,11.104 4.954,11.16 4.954,11.218C4.954,11.747 5.383,12.176 5.912,12.176C6.395,12.176 6.795,11.819 6.861,11.354C7.233,9.044 9.044,7.233 11.354,6.861Z"
android:fillColor="#ffffff"
android:fillAlpha="0.6"
android:fillType="evenOdd"/>
<path
android:pathData="M25.431,25.434C25.745,25.107 25.745,24.594 25.431,24.279L23.264,22.111C22.938,21.796 22.425,21.796 22.111,22.111C21.796,22.437 21.796,22.95 22.111,23.265L24.278,25.434C24.429,25.585 24.639,25.667 24.848,25.667C25.058,25.667 25.268,25.585 25.431,25.434Z"
android:fillColor="#ffffff"
android:fillAlpha="0.6"/>
</group>
android:fillColor="#00000000"
android:pathData="M18,18m-17.5,0a17.5,17.5 0,1 1,35 0a17.5,17.5 0,1 1,-35 0"
android:strokeWidth="1"
android:strokeColor="#9C9D9D" />
<group>
<clip-path android:pathData="M32,4l-28,0l-0,28l28,0z" />
<path
android:fillColor="#9C9D9D"
android:fillType="evenOdd"
android:pathData="M17.5,6C11.149,6 6,11.149 6,17.5C6,23.851 11.149,29 17.5,29C23.851,29 29,23.851 29,17.5C29,11.149 23.851,6 17.5,6ZM15.354,10.861C15.819,10.795 16.176,10.395 16.176,9.912C16.176,9.383 15.747,8.954 15.218,8.954C15.16,8.954 15.104,8.959 15.049,8.968C11.923,9.472 9.472,11.923 8.968,15.049C8.959,15.104 8.954,15.16 8.954,15.218C8.954,15.747 9.383,16.176 9.912,16.176C10.395,16.176 10.795,15.819 10.861,15.354C11.233,13.044 13.044,11.233 15.354,10.861Z" />
<path
android:fillColor="#9C9D9D"
android:pathData="M29.431,29.434C29.745,29.107 29.745,28.594 29.431,28.279L27.264,26.111C26.938,25.796 26.425,25.796 26.111,26.111C25.796,26.437 25.796,26.95 26.111,27.265L28.278,29.434C28.429,29.585 28.639,29.667 28.848,29.667C29.058,29.667 29.268,29.585 29.431,29.434Z" />
</group>
</vector>

View File

@ -100,90 +100,105 @@
android:textSize="16dp" />
</LinearLayout>
<LinearLayout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="0dp"
app:cardCornerRadius="10dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="160dp"
android:layout_height="160dp"
android:src="@mipmap/musicoo_logo_img" />
</androidx.cardview.widget.CardView>
android:layout_height="match_parent"
android:layout_above="@+id/play_music_layout"
android:orientation="vertical">
<LinearLayout
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="0dp"
app:cardCornerRadius="10dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="160dp"
android:layout_height="160dp"
android:src="@mipmap/musicoo_logo_img" />
</androidx.cardview.widget.CardView>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/medium_font"
android:maxLines="2"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="18dp" />
<TextView
android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/medium_font"
android:maxLines="1"
android:text="@string/ready_to_sleep"
android:textColor="@color/white_60"
android:textSize="12dp" />
<TextView
android:id="@+id/secondSubtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:fontFamily="@font/regular_font"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="@color/white_60"
android:textSize="12dp" />
</LinearLayout>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/medium_font"
android:maxLines="2"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="18dp" />
<TextView
android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/medium_font"
android:maxLines="1"
android:text="@string/ready_to_sleep"
android:textColor="@color/white_60"
android:textSize="12dp" />
<TextView
android:id="@+id/secondSubtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:fontFamily="@font/regular_font"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="@color/white_60"
android:textSize="12dp" />
</LinearLayout>
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:overScrollMode="never"
android:scrollbars="none" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
<LinearLayout
android:id="@+id/play_music_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:overScrollMode="never"
android:scrollbars="none" />
</LinearLayout>
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical" />
</RelativeLayout>
</LinearLayout>

View File

@ -104,20 +104,6 @@
</LinearLayout>
<LinearLayout
android:id="@+id/alarm_clock_btn"
android:layout_width="42dp"
android:visibility="gone"
android:layout_height="42dp"
android:gravity="center">
<ImageView
android:layout_width="34dp"
android:layout_height="34dp"
android:src="@drawable/alarm_clock_icon" />
</LinearLayout>
<LinearLayout
android:id="@+id/play_black_btn"
android:layout_width="42dp"

View File

@ -126,8 +126,8 @@
android:id="@+id/playback_error_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="@color/black_60"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
@ -149,9 +149,9 @@
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/drw_btn_bg"
android:fontFamily="@font/medium_font"
android:paddingStart="24dp"
android:paddingTop="8dp"
android:fontFamily="@font/medium_font"
android:paddingEnd="24dp"
android:paddingBottom="8dp"
android:text="@string/try_again"
@ -294,15 +294,17 @@
android:orientation="horizontal">
<LinearLayout
android:id="@+id/playModeBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center">
<ImageView
android:id="@+id/modePlayImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/play_mode_icon" />
android:src="@drawable/mode_cycle_play_icon" />
</LinearLayout>
<LinearLayout
@ -409,10 +411,10 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/playListRv"
android:layout_width="match_parent"
android:scrollbars="none"
android:overScrollMode="never"
android:layout_height="match_parent"
android:layout_margin="16dp" />
android:layout_margin="16dp"
android:overScrollMode="never"
android:scrollbars="none" />
</LinearLayout>

View File

@ -38,126 +38,11 @@
android:layout_alignParentBottom="true"
android:orientation="vertical">
<com.lihang.ShadowLayout
android:id="@+id/playing_status_layout"
<LinearLayout
android:id="@+id/play_music_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:visibility="visible"
app:hl_cornerRadius="36dp"
app:hl_layoutBackground="#FF80F988"
app:hl_shadowColor="#40040604"
app:hl_shadowOffsetX="0dp"
app:hl_shadowOffsetY="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="68dp"
android:layout_alignParentBottom="true"
android:gravity="center_vertical"
android:paddingStart="20dp"
android:paddingEnd="20dp">
<LinearLayout
android:id="@+id/goDetailsBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:elevation="0dp"
app:cardCornerRadius="24dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/audio_img"
android:layout_width="48dp"
android:scaleType="centerCrop"
android:layout_height="48dp"
android:src="@mipmap/musicoo_logo_img" />
</androidx.cardview.widget.CardView>
<com.player.musicoo.view.CircularProgressBar
android:id="@+id/progressBar"
android:layout_width="54dp"
android:layout_height="54dp"
android:layout_centerInParent="true" />
</RelativeLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical">
<com.player.musicoo.view.MarqueeTextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:fontFamily="@font/medium_font"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="@color/black"
android:textSize="16dp" />
<com.player.musicoo.view.MarqueeTextView
android:id="@+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="@color/black_60"
android:textSize="12dp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/alarm_clock_btn"
android:layout_width="42dp"
android:layout_height="42dp"
android:gravity="center"
android:visibility="gone">
<ImageView
android:layout_width="34dp"
android:layout_height="34dp"
android:src="@drawable/alarm_clock_icon" />
</LinearLayout>
<LinearLayout
android:id="@+id/play_black_btn"
android:layout_width="42dp"
android:layout_height="42dp"
android:gravity="center">
<ImageView
android:id="@+id/play_status_img"
android:layout_width="34dp"
android:layout_height="34dp"
android:src="@drawable/play_black_icon" />
</LinearLayout>
</LinearLayout>
</com.lihang.ShadowLayout>
android:orientation="vertical" />
<RelativeLayout
android:id="@+id/tab_layout"
@ -200,17 +85,17 @@
<LinearLayout
android:id="@+id/import_btn"
android:id="@+id/me_btn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center">
<ImageView
android:id="@+id/import_img"
android:id="@+id/me_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/import_unselect_icon" />
android:src="@drawable/me_unselect_icon" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>

View File

@ -106,25 +106,40 @@
android:textSize="16dp" />
</LinearLayout>
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/refreshLayout"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:overScrollMode="never"
android:scrollbars="none" />
android:layout_above="@+id/play_music_layout">
<com.scwang.smart.refresh.footer.BallPulseFooter
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:overScrollMode="never"
android:scrollbars="none" />
<com.scwang.smart.refresh.footer.BallPulseFooter
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srlAnimatingColor="@color/green" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<LinearLayout
android:id="@+id/play_music_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srlAnimatingColor="@color/green" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
android:layout_alignParentBottom="true"
android:orientation="vertical" />
</RelativeLayout>
</LinearLayout>

View File

@ -138,67 +138,81 @@
android:textSize="16dp" />
</LinearLayout>
<androidx.core.widget.NestedScrollView
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_above="@+id/play_music_layout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/singerName"
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="68dp"
android:fontFamily="@font/medium_font"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="22dp" />
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/singerDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:fontFamily="@font/regular_font"
android:maxLines="2"
android:text="@string/app_name"
android:textColor="@color/white_60"
android:textSize="14dp" />
<TextView
android:id="@+id/singerName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="68dp"
android:fontFamily="@font/medium_font"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="22dp" />
<TextView
android:id="@+id/singerDescExpand"
android:layout_width="wrap_content"
<TextView
android:id="@+id/singerDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:fontFamily="@font/regular_font"
android:maxLines="2"
android:text="@string/app_name"
android:textColor="@color/white_60"
android:textSize="14dp" />
<TextView
android:id="@+id/singerDescExpand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:ellipsize="end"
android:fontFamily="@font/regular_font"
android:text="@string/expand"
android:textColor="@color/white_60"
android:textSize="12dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:ellipsize="end"
android:fontFamily="@font/regular_font"
android:text="@string/expand"
android:textColor="@color/white_60"
android:textSize="12dp" />
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:orientation="vertical" />
</LinearLayout>
<LinearLayout
android:id="@+id/content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:orientation="vertical" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.core.widget.NestedScrollView>
<LinearLayout
android:id="@+id/play_music_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical" />
</RelativeLayout>
</LinearLayout>

View File

@ -45,6 +45,21 @@
android:text="1"
android:textColor="@color/white"
android:textSize="16dp" />
<RelativeLayout
android:id="@+id/currentPlayingLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/black_60"
android:layout_centerInParent="true"
android:visibility="gone">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/playing_small_green_icon" />
</RelativeLayout>
</RelativeLayout>
<LinearLayout

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="0dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/view"
android:orientation="vertical">
</LinearLayout>
</RelativeLayout>

View File

@ -40,10 +40,10 @@
android:orientation="horizontal">
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="16dp"
android:src="@drawable/search_unselect_icon" />
android:src="@drawable/search_edit_icon" />
<EditText
android:id="@+id/searchEdit"
@ -67,8 +67,8 @@
android:visibility="gone">
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerInParent="true"
android:src="@drawable/cha_icon" />
</RelativeLayout>
@ -78,7 +78,7 @@
android:id="@+id/cancelBtn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_marginStart="16dp"
android:fontFamily="@font/regular_font"
android:gravity="center"
android:text="@string/cancel"

View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.lihang.ShadowLayout
android:id="@+id/playing_status_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:visibility="visible"
app:hl_cornerRadius="36dp"
app:hl_layoutBackground="#FF80F988"
app:hl_shadowColor="#40040604"
app:hl_shadowOffsetX="0dp"
app:hl_shadowOffsetY="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="68dp"
android:layout_alignParentBottom="true"
android:gravity="center_vertical"
android:paddingStart="20dp"
android:paddingEnd="20dp">
<LinearLayout
android:id="@+id/goDetailsBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:elevation="0dp"
app:cardCornerRadius="24dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/audio_img"
android:layout_width="48dp"
android:scaleType="centerCrop"
android:layout_height="48dp"
android:src="@mipmap/musicoo_logo_img" />
</androidx.cardview.widget.CardView>
<com.player.musicoo.view.CircularProgressBar
android:id="@+id/progressBar"
android:layout_width="54dp"
android:layout_height="54dp"
android:layout_centerInParent="true" />
</RelativeLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical">
<com.player.musicoo.view.MarqueeTextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:fontFamily="@font/medium_font"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="@color/black"
android:textSize="16dp" />
<com.player.musicoo.view.MarqueeTextView
android:id="@+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="@color/black_60"
android:textSize="12dp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/play_black_btn"
android:layout_width="42dp"
android:layout_height="42dp"
android:gravity="center">
<ImageView
android:id="@+id/play_status_img"
android:layout_width="34dp"
android:layout_height="34dp"
android:src="@drawable/play_black_icon" />
</LinearLayout>
</LinearLayout>
</com.lihang.ShadowLayout>
</LinearLayout>

View File

@ -37,20 +37,6 @@
android:scaleType="centerCrop"
android:src="@mipmap/musicoo_logo_img" />
<RelativeLayout
android:id="@+id/currentPlayingLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black_60"
android:gravity="center"
android:visibility="gone">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/playing_small_green_icon" />
</RelativeLayout>
</RelativeLayout>
</androidx.cardview.widget.CardView>