This commit is contained in:
ocean 2024-04-23 19:27:05 +08:00
parent 8f15461f14
commit 830ad770eb
13 changed files with 702 additions and 0 deletions

View File

@ -47,6 +47,9 @@
<activity <activity
android:name=".activity.AboutActivity" android:name=".activity.AboutActivity"
android:screenOrientation="portrait" /> android:screenOrientation="portrait" />
<activity
android:name=".activity.DetailsActivity"
android:screenOrientation="portrait" />
<service <service
android:name=".service.PlaybackService" android:name=".service.PlaybackService"

View File

@ -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}")
}
}
}

View File

@ -1,15 +1,33 @@
package com.player.musicoo.activity 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.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 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.sp.AppStore
import com.player.musicoo.util.LogTag import com.player.musicoo.util.LogTag
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.IOException
import java.io.InputStream
abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope() { 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()
}
}
} }

View File

@ -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)
}
}

View File

@ -2,6 +2,7 @@ package com.player.musicoo.adapter
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -9,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.player.musicoo.App import com.player.musicoo.App
import com.player.musicoo.R import com.player.musicoo.R
import com.player.musicoo.activity.DetailsActivity
import com.player.musicoo.activity.PlayDetailsActivity import com.player.musicoo.activity.PlayDetailsActivity
import com.player.musicoo.bean.Audio import com.player.musicoo.bean.Audio
import com.player.musicoo.databinding.MusicResponsiveItemBinding 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.SoundsOfAppliancesLayoutBinding
import com.player.musicoo.databinding.SoundsOfNatureLayoutBinding import com.player.musicoo.databinding.SoundsOfNatureLayoutBinding
import com.player.musicoo.innertube.models.MusicCarouselShelfRenderer import com.player.musicoo.innertube.models.MusicCarouselShelfRenderer
import com.player.musicoo.util.LogTag
import com.player.musicoo.util.convertMillisToMinutesAndSecondsString import com.player.musicoo.util.convertMillisToMinutesAndSecondsString
import com.player.musicoo.util.getAudioDurationFromAssets import com.player.musicoo.util.getAudioDurationFromAssets
@ -33,7 +36,23 @@ class TowRowListAdapter(
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val bean = list[position] val bean = list[position]
val browseEndpoint = bean.musicTwoRowItemRenderer
?.title
?.runs
?.firstOrNull()
?.navigationEndpoint
?.browseEndpoint
val browseId = browseEndpoint?.browseId
holder.bind(bean) 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 override fun getItemCount(): Int = list.size

View File

@ -177,6 +177,28 @@ object Innertube {
val contents: List<MusicCarouselShelfRenderer.Content> 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( data class ArtistPage(
val name: String?, val name: String?,
val description: String?, val description: String?,

View File

@ -41,6 +41,7 @@ data class BrowseResponse(
val subtitle: Runs?, val subtitle: Runs?,
val secondSubtitle: Runs?, val secondSubtitle: Runs?,
val thumbnail: ThumbnailRenderer?, val thumbnail: ThumbnailRenderer?,
val description: Runs?
) )
@Serializable @Serializable

View File

@ -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
)
}

View 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>

View 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>

View 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>

View File

@ -4,6 +4,7 @@
<color name="black_60">#99000000</color> <color name="black_60">#99000000</color>
<color name="white">#FFFFFFFF</color> <color name="white">#FFFFFFFF</color>
<color name="white_60">#99FFFFFF</color> <color name="white_60">#99FFFFFF</color>
<color name="white_80">#CCFFFFFF</color>
<color name="main_bg_color">#151718</color> <color name="main_bg_color">#151718</color>
<color name="green">#FF80F988</color> <color name="green">#FF80F988</color>
</resources> </resources>

View File

@ -16,4 +16,6 @@
<string name="terms_of_service">Terms of Service</string> <string name="terms_of_service">Terms of Service</string>
<string name="listen_music_anytime">Listen Music Anytime</string> <string name="listen_music_anytime">Listen Music Anytime</string>
<string name="resource_loading">Resource Loading…</string> <string name="resource_loading">Resource Loading…</string>
<string name="expand">EXPAND</string>
<string name="description">Description</string>
</resources> </resources>