update
This commit is contained in:
parent
8f15461f14
commit
830ad770eb
@ -47,6 +47,9 @@
|
||||
<activity
|
||||
android:name=".activity.AboutActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".activity.DetailsActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<service
|
||||
android:name=".service.PlaybackService"
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
package com.player.musicoo.activity
|
||||
|
||||
import android.util.Log
|
||||
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.innertube.Innertube
|
||||
import com.player.musicoo.innertube.requests.moPlaylistPage
|
||||
|
||||
class DetailsActivity : MoBaseActivity() {
|
||||
|
||||
companion object {
|
||||
const val PLAY_LIST_PAGE_BROWSE_ID = "play_list_page_browse_id"
|
||||
}
|
||||
|
||||
private lateinit var binding: ActivityDetailsBinding
|
||||
|
||||
override suspend fun main() {
|
||||
binding = ActivityDetailsBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
initImmersionBar()
|
||||
val browseId = intent.getStringExtra(PLAY_LIST_PAGE_BROWSE_ID)
|
||||
if (browseId.isNullOrEmpty() || browseId == "null") {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
initView()
|
||||
Log.d(TAG, "browseId->${browseId}")
|
||||
initData(browseId)
|
||||
}
|
||||
|
||||
private fun initImmersionBar() {
|
||||
immersionBar {
|
||||
statusBarDarkFont(false)
|
||||
statusBarView(binding.view)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
binding.backBtn.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun initData(browseId: String) {
|
||||
Innertube.moPlaylistPage(browseId)
|
||||
?.onSuccess {
|
||||
Glide.with(this)
|
||||
.load(it.thumbnail)
|
||||
.into(binding.imageView)
|
||||
|
||||
binding.title.text = it.title
|
||||
binding.subtitle.text = it.subtitle
|
||||
binding.secondSubtitle.text = it.secondSubtitle
|
||||
|
||||
val adapter = DetailsListAdapter(this, it.moPlaylistOrAlbumListBean)
|
||||
binding.rv.layoutManager =
|
||||
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
||||
binding.rv.adapter = adapter
|
||||
|
||||
}?.onFailure {
|
||||
Log.d(TAG, "moPlaylistPage onFailure->${it}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,15 +1,33 @@
|
||||
package com.player.musicoo.activity
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.renderscript.Allocation
|
||||
import android.renderscript.Element
|
||||
import android.renderscript.RenderScript
|
||||
import android.renderscript.ScriptIntrinsicBlur
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.player.musicoo.R
|
||||
import com.player.musicoo.sp.AppStore
|
||||
import com.player.musicoo.util.LogTag
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope() {
|
||||
|
||||
@ -70,4 +88,63 @@ 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 applyGaussianBlur(inputBitmap: Bitmap, radius: Float, context: Context): Bitmap {
|
||||
val rsContext = RenderScript.create(context)
|
||||
val outputBitmap =
|
||||
Bitmap.createBitmap(inputBitmap.width, inputBitmap.height, inputBitmap.config)
|
||||
val blurScript = ScriptIntrinsicBlur.create(rsContext, Element.U8_4(rsContext))
|
||||
val tmpIn = Allocation.createFromBitmap(rsContext, inputBitmap)
|
||||
val tmpOut = Allocation.createFromBitmap(rsContext, outputBitmap)
|
||||
blurScript.setRadius(radius)
|
||||
blurScript.setInput(tmpIn)
|
||||
blurScript.forEach(tmpOut)
|
||||
tmpOut.copyTo(outputBitmap)
|
||||
rsContext.finish()
|
||||
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)
|
||||
val title = dialogView.findViewById<TextView>(R.id.dialog_title)
|
||||
title.text = getString(R.string.description)
|
||||
val content = dialogView.findViewById<TextView>(R.id.dialog_content)
|
||||
content.text = description
|
||||
val okBtn = dialogView.findViewById<TextView>(R.id.dialog_ok_btn)
|
||||
val dialogBuilder = AlertDialog.Builder(this)
|
||||
.setView(dialogView)
|
||||
val dialog = dialogBuilder.create()
|
||||
dialog.show()
|
||||
okBtn.setOnClickListener {
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package com.player.musicoo.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.player.musicoo.App
|
||||
import com.player.musicoo.R
|
||||
import com.player.musicoo.activity.PlayDetailsActivity
|
||||
import com.player.musicoo.bean.Audio
|
||||
import com.player.musicoo.databinding.DetailsListItemBinding
|
||||
import com.player.musicoo.databinding.MusicResponsiveItemBinding
|
||||
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.util.convertMillisToMinutesAndSecondsString
|
||||
import com.player.musicoo.util.getAudioDurationFromAssets
|
||||
|
||||
class DetailsListAdapter(
|
||||
private val context: Context,
|
||||
private val list: List<Innertube.MoPlaylistOrAlbumPage.MoPlaylistOrAlbumListBean>,
|
||||
) :
|
||||
RecyclerView.Adapter<DetailsListAdapter.ViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val binding = DetailsListItemBinding.inflate(LayoutInflater.from(context), parent, false)
|
||||
return ViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val bean = list[position]
|
||||
holder.bind(bean)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = list.size
|
||||
|
||||
inner class ViewHolder(private val binding: DetailsListItemBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun bind(bean: Innertube.MoPlaylistOrAlbumPage.MoPlaylistOrAlbumListBean) {
|
||||
|
||||
binding.apply {
|
||||
if (!bean.thumbnailUrl.isNullOrEmpty()) {
|
||||
image.visibility = View.VISIBLE
|
||||
Glide.with(context)
|
||||
.load(bean.thumbnailUrl)
|
||||
.into(image)
|
||||
sortTv.visibility = View.GONE
|
||||
} else {
|
||||
image.visibility = View.GONE
|
||||
sortTv.visibility = View.VISIBLE
|
||||
sortTv.text = "${bindingAdapterPosition + 1}"
|
||||
}
|
||||
|
||||
title.text = bean.title
|
||||
if (bean.name.isNullOrEmpty()) {
|
||||
name.visibility = View.GONE
|
||||
} else {
|
||||
name.visibility = View.VISIBLE
|
||||
name.text = bean.name
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var itemClickListener: OnItemClickListener? = null
|
||||
|
||||
fun setOnItemClickListener(listener: OnItemClickListener) {
|
||||
itemClickListener = listener
|
||||
}
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onItemClick(position: Int)
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ package com.player.musicoo.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@ -9,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.player.musicoo.App
|
||||
import com.player.musicoo.R
|
||||
import com.player.musicoo.activity.DetailsActivity
|
||||
import com.player.musicoo.activity.PlayDetailsActivity
|
||||
import com.player.musicoo.bean.Audio
|
||||
import com.player.musicoo.databinding.MusicResponsiveItemBinding
|
||||
@ -16,6 +18,7 @@ import com.player.musicoo.databinding.MusicTowRowItemBinding
|
||||
import com.player.musicoo.databinding.SoundsOfAppliancesLayoutBinding
|
||||
import com.player.musicoo.databinding.SoundsOfNatureLayoutBinding
|
||||
import com.player.musicoo.innertube.models.MusicCarouselShelfRenderer
|
||||
import com.player.musicoo.util.LogTag
|
||||
import com.player.musicoo.util.convertMillisToMinutesAndSecondsString
|
||||
import com.player.musicoo.util.getAudioDurationFromAssets
|
||||
|
||||
@ -33,7 +36,23 @@ class TowRowListAdapter(
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val bean = list[position]
|
||||
|
||||
val browseEndpoint = bean.musicTwoRowItemRenderer
|
||||
?.title
|
||||
?.runs
|
||||
?.firstOrNull()
|
||||
?.navigationEndpoint
|
||||
?.browseEndpoint
|
||||
|
||||
val browseId = browseEndpoint?.browseId
|
||||
|
||||
holder.bind(bean)
|
||||
|
||||
holder.itemView.setOnClickListener {
|
||||
val intent = Intent(context, DetailsActivity::class.java)
|
||||
intent.putExtra(DetailsActivity.PLAY_LIST_PAGE_BROWSE_ID, browseId)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = list.size
|
||||
|
||||
@ -177,6 +177,28 @@ object Innertube {
|
||||
val contents: List<MusicCarouselShelfRenderer.Content>
|
||||
)
|
||||
|
||||
data class MoPlaylistOrAlbumPage(
|
||||
val title: String?,
|
||||
val subtitle: String?,
|
||||
val thumbnail: String?,
|
||||
val secondSubtitle: String?,
|
||||
val description: String?,
|
||||
val moPlaylistOrAlbumListBean: List<MoPlaylistOrAlbumListBean>
|
||||
) {
|
||||
data class MoPlaylistOrAlbumListBean(
|
||||
val title: String?,
|
||||
val name: String?,
|
||||
val desc: String?,
|
||||
val timeText: String?,
|
||||
val browseId: String,
|
||||
val videoId: String?,
|
||||
val playlistId: String?,
|
||||
val musicVideoType: String?,
|
||||
val pageType: String?,
|
||||
val thumbnailUrl: String?
|
||||
)
|
||||
}
|
||||
|
||||
data class ArtistPage(
|
||||
val name: String?,
|
||||
val description: String?,
|
||||
|
||||
@ -41,6 +41,7 @@ data class BrowseResponse(
|
||||
val subtitle: Runs?,
|
||||
val secondSubtitle: Runs?,
|
||||
val thumbnail: ThumbnailRenderer?,
|
||||
val description: Runs?
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
||||
@ -0,0 +1,135 @@
|
||||
package com.player.musicoo.innertube.requests
|
||||
|
||||
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 io.ktor.client.call.body
|
||||
import io.ktor.client.request.post
|
||||
import io.ktor.client.request.setBody
|
||||
|
||||
suspend fun Innertube.moPlaylistPage(browseId: String): Result<Innertube.MoPlaylistOrAlbumPage>? =
|
||||
runCatchingNonCancellable {
|
||||
val response = client.post(browse) {
|
||||
setBody(BrowseBody(browseId = browseId))
|
||||
}.body<BrowseResponse>()
|
||||
|
||||
|
||||
val musicDetailHeaderRenderer = response
|
||||
.header
|
||||
?.musicDetailHeaderRenderer
|
||||
|
||||
val sectionListRendererContents = response
|
||||
.contents
|
||||
?.singleColumnBrowseResultsRenderer
|
||||
?.tabs
|
||||
?.firstOrNull()
|
||||
?.tabRenderer
|
||||
?.content
|
||||
?.sectionListRenderer
|
||||
?.contents
|
||||
|
||||
val musicShelfRenderer = sectionListRendererContents
|
||||
?.firstOrNull()
|
||||
?.musicShelfRenderer
|
||||
|
||||
val musicCarouselShelfRenderer = sectionListRendererContents
|
||||
?.getOrNull(1)
|
||||
?.musicCarouselShelfRenderer
|
||||
|
||||
val list: MutableList<Innertube.MoPlaylistOrAlbumPage.MoPlaylistOrAlbumListBean> =
|
||||
mutableListOf()
|
||||
list.clear()
|
||||
val contents = musicShelfRenderer?.contents
|
||||
if (contents != null) {
|
||||
for (content: MusicShelfRenderer.Content in contents) {
|
||||
val runs0 = content.musicResponsiveListItemRenderer
|
||||
?.flexColumns
|
||||
?.getOrNull(0)
|
||||
?.musicResponsiveListItemFlexColumnRenderer
|
||||
?.text
|
||||
?.runs
|
||||
?.firstOrNull()
|
||||
val watchEndpoint = runs0?.navigationEndpoint?.watchEndpoint
|
||||
val runs1 = content.musicResponsiveListItemRenderer
|
||||
?.flexColumns
|
||||
?.getOrNull(1)
|
||||
?.musicResponsiveListItemFlexColumnRenderer
|
||||
?.text
|
||||
?.runs
|
||||
?.firstOrNull()
|
||||
val browseEndpoint = runs1?.navigationEndpoint?.browseEndpoint
|
||||
|
||||
val runs2 = content.musicResponsiveListItemRenderer
|
||||
?.flexColumns
|
||||
?.getOrNull(2)
|
||||
?.musicResponsiveListItemFlexColumnRenderer
|
||||
?.text
|
||||
?.runs
|
||||
?.firstOrNull()
|
||||
|
||||
val thumbnailUrl = content.musicResponsiveListItemRenderer
|
||||
?.thumbnail
|
||||
?.musicThumbnailRenderer
|
||||
?.thumbnail
|
||||
?.thumbnails
|
||||
?.firstOrNull()
|
||||
?.url
|
||||
|
||||
|
||||
val bean = Innertube.MoPlaylistOrAlbumPage.MoPlaylistOrAlbumListBean(
|
||||
title = runs0?.text,
|
||||
name = runs1?.text,
|
||||
desc = runs2?.text,
|
||||
timeText = content.musicResponsiveListItemRenderer
|
||||
?.fixedColumns?.firstOrNull()
|
||||
?.musicResponsiveListItemFlexColumnRenderer
|
||||
?.text
|
||||
?.runs
|
||||
?.firstOrNull()
|
||||
?.text,
|
||||
browseId = browseEndpoint?.browseId.toString(),
|
||||
videoId = watchEndpoint?.videoId,
|
||||
playlistId = watchEndpoint?.playlistId,
|
||||
musicVideoType = watchEndpoint?.type,
|
||||
pageType = browseEndpoint?.type,
|
||||
thumbnailUrl = thumbnailUrl
|
||||
)
|
||||
|
||||
list.add(bean)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Innertube.MoPlaylistOrAlbumPage(
|
||||
title = musicDetailHeaderRenderer
|
||||
?.title
|
||||
?.runs
|
||||
?.firstOrNull()
|
||||
?.text,
|
||||
subtitle = musicDetailHeaderRenderer
|
||||
?.subtitle
|
||||
?.runs
|
||||
?.map { it.text }
|
||||
?.joinToString(""),
|
||||
thumbnail = musicDetailHeaderRenderer
|
||||
?.thumbnail
|
||||
?.musicThumbnailRenderer
|
||||
?.thumbnail
|
||||
?.thumbnails
|
||||
?.let { it.getOrNull(3) ?: it.getOrNull(2) ?: it.getOrNull(1) ?: it.getOrNull(0) }
|
||||
?.url,
|
||||
secondSubtitle = musicDetailHeaderRenderer
|
||||
?.secondSubtitle
|
||||
?.runs
|
||||
?.map { it.text }
|
||||
?.joinToString(""),
|
||||
description = musicDetailHeaderRenderer
|
||||
?.description
|
||||
?.runs
|
||||
?.firstOrNull()
|
||||
?.text,
|
||||
moPlaylistOrAlbumListBean = list
|
||||
)
|
||||
}
|
||||
122
app/src/main/res/layout/activity_details.xml
Normal file
122
app/src/main/res/layout/activity_details.xml
Normal file
@ -0,0 +1,122 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/main_bg_color"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@mipmap/settings_bg_img" />
|
||||
|
||||
<View
|
||||
android:id="@+id/view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/title_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/view"
|
||||
android:layout_margin="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/back_btn"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="42dp"
|
||||
android:background="@drawable/drw_back_bg">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@drawable/back_icon" />
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/title_layout"
|
||||
android:orientation="vertical">
|
||||
|
||||
<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>
|
||||
|
||||
<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="wrap_content"
|
||||
android:layout_margin="16dp" />
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
80
app/src/main/res/layout/details_list_item.xml
Normal file
80
app/src/main/res/layout/details_list_item.xml
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="MissingDefaultResource">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingBottom="12dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="0dp"
|
||||
android:visibility="visible"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@mipmap/musicoo_logo_img" />
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sort_tv"
|
||||
android:layout_width="22dp"
|
||||
android:gravity="center"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:fontFamily="@font/medium_font"
|
||||
android:text="1"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16dp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.player.musicoo.view.MarqueeTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/regular_font"
|
||||
android:maxLines="1"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14dp" />
|
||||
|
||||
<com.player.musicoo.view.MarqueeTextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/regular_font"
|
||||
android:maxLines="1"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/white_60"
|
||||
android:textSize="12dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
91
app/src/main/res/layout/dialog_description.xml
Normal file
91
app/src/main/res/layout/dialog_description.xml
Normal file
@ -0,0 +1,91 @@
|
||||
<!-- custom_dialog_layout.xml -->
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="0dp"
|
||||
android:orientation="vertical"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/main_bg_color"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:src="@mipmap/musicoo_logo_img" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:fontFamily="@font/medium_font"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:fontFamily="@font/regular_font"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/white_60"
|
||||
android:textSize="14dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_cancel_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:fontFamily="@font/medium_font"
|
||||
android:gravity="center"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:text="@string/cancel"
|
||||
android:textColor="@color/white_60"
|
||||
android:textSize="16dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_ok_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="16dp"
|
||||
android:fontFamily="@font/medium_font"
|
||||
android:gravity="center"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:text="@string/ok"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
@ -4,6 +4,7 @@
|
||||
<color name="black_60">#99000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
<color name="white_60">#99FFFFFF</color>
|
||||
<color name="white_80">#CCFFFFFF</color>
|
||||
<color name="main_bg_color">#151718</color>
|
||||
<color name="green">#FF80F988</color>
|
||||
</resources>
|
||||
@ -16,4 +16,6 @@
|
||||
<string name="terms_of_service">Terms of Service</string>
|
||||
<string name="listen_music_anytime">Listen Music Anytime</string>
|
||||
<string name="resource_loading">Resource Loading…</string>
|
||||
<string name="expand">EXPAND</string>
|
||||
<string name="description">Description</string>
|
||||
</resources>
|
||||
Loading…
Reference in New Issue
Block a user