增加书籍详情界面与有声书界面的根据封面生成主题色功能
This commit is contained in:
6 files changed
+621
-209
No files matched your search
@@ -1,8 +1,15 @@
|
|||||||
package io.legato.kazusa.ui.book.audio
|
package io.legato.kazusa.ui.book.audio
|
||||||
|
|
||||||
|
import android.animation.ValueAnimator
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.res.ColorStateList
|
||||||
|
import android.graphics.Color
|
||||||
import android.graphics.RenderEffect
|
import android.graphics.RenderEffect
|
||||||
import android.graphics.Shader
|
import android.graphics.Shader
|
||||||
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.graphics.drawable.TransitionDrawable
|
||||||
import android.icu.text.SimpleDateFormat
|
import android.icu.text.SimpleDateFormat
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -11,10 +18,15 @@ import android.view.Menu
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
|
import androidx.core.graphics.scale
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.transition.TransitionManager
|
import androidx.transition.TransitionManager
|
||||||
|
import com.google.android.material.color.DynamicColors
|
||||||
|
import com.google.android.material.color.DynamicColorsOptions
|
||||||
|
import com.google.android.material.color.MaterialColors
|
||||||
import com.google.android.material.slider.Slider
|
import com.google.android.material.slider.Slider
|
||||||
|
import com.google.android.material.transition.platform.MaterialContainerTransform
|
||||||
import io.legato.kazusa.R
|
import io.legato.kazusa.R
|
||||||
import io.legato.kazusa.base.VMBaseActivity
|
import io.legato.kazusa.base.VMBaseActivity
|
||||||
import io.legato.kazusa.constant.BookType
|
import io.legato.kazusa.constant.BookType
|
||||||
@@ -50,7 +62,10 @@ import io.legato.kazusa.utils.startActivityForBook
|
|||||||
import io.legato.kazusa.utils.startAnimation
|
import io.legato.kazusa.utils.startAnimation
|
||||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||||
import io.legato.kazusa.utils.visible
|
import io.legato.kazusa.utils.visible
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import splitties.views.onLongClick
|
import splitties.views.onLongClick
|
||||||
@@ -70,6 +85,13 @@ class AudioPlayActivity :
|
|||||||
private var adjustProgress = false
|
private var adjustProgress = false
|
||||||
private var playMode = AudioPlay.PlayMode.LIST_END_STOP
|
private var playMode = AudioPlay.PlayMode.LIST_END_STOP
|
||||||
private var playSpeed = 1f
|
private var playSpeed = 1f
|
||||||
|
private var primaryFinalColor: Int = 0
|
||||||
|
private var surfaceFinalColor: Int = 0
|
||||||
|
private var secondaryFinalColor: Int = 0
|
||||||
|
private var onSurfaceFinalColor: Int = 0
|
||||||
|
private var secondaryContainerFinalColor: Int = 0
|
||||||
|
private var currentJob: Job? = null
|
||||||
|
private var wrappedContext: Context? = null
|
||||||
|
|
||||||
private val progressTimeFormat by lazy {
|
private val progressTimeFormat by lazy {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
@@ -95,7 +117,27 @@ class AudioPlayActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
val transform = MaterialContainerTransform().apply {
|
||||||
|
addTarget(binding.root)
|
||||||
|
scrimColor = Color.TRANSPARENT
|
||||||
|
}
|
||||||
|
window.sharedElementEnterTransition = transform
|
||||||
|
window.sharedElementReturnTransition = transform
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
binding.root.transitionName = intent.getStringExtra("transitionName")
|
||||||
|
primaryFinalColor =
|
||||||
|
MaterialColors.getColor(this, androidx.appcompat.R.attr.colorPrimary, -1)
|
||||||
|
surfaceFinalColor =
|
||||||
|
MaterialColors.getColor(this, com.google.android.material.R.attr.colorSurface, -1)
|
||||||
|
secondaryFinalColor =
|
||||||
|
MaterialColors.getColor(this, com.google.android.material.R.attr.colorSecondary, -1)
|
||||||
|
onSurfaceFinalColor =
|
||||||
|
MaterialColors.getColor(this, com.google.android.material.R.attr.colorOnSurface, -1)
|
||||||
|
secondaryContainerFinalColor = MaterialColors.getColor(
|
||||||
|
this,
|
||||||
|
com.google.android.material.R.attr.colorSecondaryContainer,
|
||||||
|
-1
|
||||||
|
)
|
||||||
binding.titleBar.setBackgroundResource(R.color.transparent)
|
binding.titleBar.setBackgroundResource(R.color.transparent)
|
||||||
binding.titleBar.title = ""
|
binding.titleBar.title = ""
|
||||||
AudioPlay.register(this)
|
AudioPlay.register(this)
|
||||||
@@ -318,25 +360,29 @@ class AudioPlayActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun upCover(path: String?) {
|
private fun upCover(path: String?) {
|
||||||
BookCover.load(this, path, sourceOrigin = AudioPlay.bookSource?.bookSourceUrl) {
|
BookCover.load(
|
||||||
|
this, path, sourceOrigin = AudioPlay.bookSource?.bookSourceUrl,
|
||||||
|
onLoadFinish = {
|
||||||
|
binding.ivCover.post {
|
||||||
|
val drawable = binding.ivCover.drawable
|
||||||
|
if (drawable != null) {
|
||||||
|
addColorScheme(drawable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).into(binding.ivCover)
|
||||||
if (!AppConfig.isEInkMode) {
|
if (!AppConfig.isEInkMode) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
BookCover.load(this, path, sourceOrigin = AudioPlay.bookSource?.bookSourceUrl)
|
BookCover.load(this, path, sourceOrigin = AudioPlay.bookSource?.bookSourceUrl)
|
||||||
.into(binding.ivBg)
|
.into(binding.ivBg)
|
||||||
val blurEffect =
|
val blurEffect = RenderEffect.createBlurEffect(120f, 120f, Shader.TileMode.CLAMP)
|
||||||
RenderEffect.createBlurEffect(120f, 120f, Shader.TileMode.CLAMP)
|
|
||||||
binding.ivBg.setRenderEffect(blurEffect)
|
binding.ivBg.setRenderEffect(blurEffect)
|
||||||
} else {
|
} else {
|
||||||
// 低版本直接加载模糊图
|
// 低版本直接加载模糊图
|
||||||
BookCover.loadBlur(
|
BookCover.loadBlur(this, path, sourceOrigin = AudioPlay.bookSource?.bookSourceUrl)
|
||||||
this,
|
|
||||||
path,
|
|
||||||
sourceOrigin = AudioPlay.bookSource?.bookSourceUrl
|
|
||||||
)
|
|
||||||
.into(binding.ivBg)
|
.into(binding.ivBg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.into(binding.ivCover)
|
addColorScheme(binding.ivCover.drawable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun playButton() {
|
private fun playButton() {
|
||||||
@@ -347,6 +393,145 @@ class AudioPlayActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addColorScheme(drawable: Drawable?) {
|
||||||
|
currentJob?.cancel()
|
||||||
|
currentJob = CoroutineScope(Dispatchers.Default).launch {
|
||||||
|
val bitmap = when (drawable) {
|
||||||
|
is BitmapDrawable -> drawable.bitmap
|
||||||
|
is TransitionDrawable -> (drawable.getDrawable(1) as? BitmapDrawable)?.bitmap
|
||||||
|
else -> null
|
||||||
|
} ?: return@launch
|
||||||
|
|
||||||
|
val colorAccuracy = true
|
||||||
|
val targetWidth = if (colorAccuracy) (bitmap.width / 4).coerceAtMost(256) else 16
|
||||||
|
val targetHeight = if (colorAccuracy) (bitmap.height / 4).coerceAtMost(256) else 16
|
||||||
|
val scaledBitmap = bitmap.scale(targetWidth, targetHeight, false)
|
||||||
|
|
||||||
|
val options = DynamicColorsOptions.Builder()
|
||||||
|
.setContentBasedSource(scaledBitmap)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
wrappedContext = DynamicColors.wrapContextIfAvailable(
|
||||||
|
this@AudioPlayActivity,
|
||||||
|
options
|
||||||
|
).apply {
|
||||||
|
resources.configuration.uiMode =
|
||||||
|
this@AudioPlayActivity.resources.configuration.uiMode
|
||||||
|
}
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
applyColorScheme()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun applyColorScheme() {
|
||||||
|
val ctx = wrappedContext ?: this
|
||||||
|
|
||||||
|
val colorPrimary = MaterialColors.getColor(ctx, androidx.appcompat.R.attr.colorPrimary, -1)
|
||||||
|
val colorSecondary =
|
||||||
|
MaterialColors.getColor(ctx, com.google.android.material.R.attr.colorSecondary, -1)
|
||||||
|
val colorOnSurface =
|
||||||
|
MaterialColors.getColor(ctx, com.google.android.material.R.attr.colorOnSurface, -1)
|
||||||
|
val colorSurface =
|
||||||
|
MaterialColors.getColor(ctx, com.google.android.material.R.attr.colorSurface, -1)
|
||||||
|
val colorSurfaceContainer = MaterialColors.getColor(
|
||||||
|
ctx,
|
||||||
|
com.google.android.material.R.attr.colorSurfaceContainer,
|
||||||
|
-1
|
||||||
|
)
|
||||||
|
val colorSecondaryContainer = MaterialColors.getColor(
|
||||||
|
ctx,
|
||||||
|
com.google.android.material.R.attr.colorSecondaryContainer,
|
||||||
|
-1
|
||||||
|
)
|
||||||
|
|
||||||
|
val primaryTransition = ValueAnimator.ofArgb(primaryFinalColor, colorPrimary).apply {
|
||||||
|
duration = 400L
|
||||||
|
addUpdateListener { animation ->
|
||||||
|
val color = animation.animatedValue as Int
|
||||||
|
binding.settingSlider.thumbTintList = ColorStateList.valueOf(color)
|
||||||
|
binding.settingSlider.trackActiveTintList = ColorStateList.valueOf(color)
|
||||||
|
binding.playerProgress.thumbTintList = ColorStateList.valueOf(color)
|
||||||
|
binding.playerProgress.trackActiveTintList = ColorStateList.valueOf(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val secondaryContainerTransition =
|
||||||
|
ValueAnimator.ofArgb(secondaryContainerFinalColor, colorSecondaryContainer).apply {
|
||||||
|
duration = 400L
|
||||||
|
addUpdateListener { animation ->
|
||||||
|
val color = animation.animatedValue as Int
|
||||||
|
binding.fabPlayStop.backgroundTintList = ColorStateList.valueOf(color)
|
||||||
|
binding.btnReset.backgroundTintList = ColorStateList.valueOf(color)
|
||||||
|
binding.settingSlider.trackInactiveTintList = ColorStateList.valueOf(color)
|
||||||
|
binding.playerProgress.trackInactiveTintList = ColorStateList.valueOf(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val surfaceTransition =
|
||||||
|
ValueAnimator.ofArgb(surfaceFinalColor, colorSurfaceContainer).apply {
|
||||||
|
duration = 400L
|
||||||
|
addUpdateListener { animation ->
|
||||||
|
val color = animation.animatedValue as Int
|
||||||
|
binding.vwBg2.setBackgroundColor(color)
|
||||||
|
binding.cdTimer.setBackgroundColor(color)
|
||||||
|
binding.cdSpeed.setBackgroundColor(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val textTransition = ValueAnimator.ofArgb(onSurfaceFinalColor, colorOnSurface).apply {
|
||||||
|
duration = 400L
|
||||||
|
addUpdateListener { animation ->
|
||||||
|
val color = animation.animatedValue as Int
|
||||||
|
binding.tvSpeed.setTextColor(color)
|
||||||
|
binding.tvTimer.setTextColor(color)
|
||||||
|
binding.tvTitle.setTextColor(color)
|
||||||
|
binding.tvDurTime.setTextColor(color)
|
||||||
|
binding.tvAllTime.setTextColor(color)
|
||||||
|
binding.tvSubTitle.setTextColor(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
surfaceTransition.start()
|
||||||
|
textTransition.start()
|
||||||
|
primaryTransition.start()
|
||||||
|
secondaryContainerTransition.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
surfaceFinalColor = colorSurface
|
||||||
|
secondaryFinalColor = colorSecondary
|
||||||
|
onSurfaceFinalColor = colorOnSurface
|
||||||
|
primaryFinalColor = colorPrimary
|
||||||
|
secondaryContainerFinalColor = colorSecondaryContainer
|
||||||
|
|
||||||
|
binding.progressLoading.setIndicatorColor(colorPrimary)
|
||||||
|
|
||||||
|
val states = arrayOf(
|
||||||
|
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked),
|
||||||
|
intArrayOf(android.R.attr.state_enabled, -android.R.attr.state_checked),
|
||||||
|
intArrayOf(-android.R.attr.state_enabled)
|
||||||
|
)
|
||||||
|
|
||||||
|
val colors = intArrayOf(
|
||||||
|
colorSurface,
|
||||||
|
colorOnSurface,
|
||||||
|
colorOnSurface.copy(alpha = 0.3f)
|
||||||
|
)
|
||||||
|
|
||||||
|
val stateList = ColorStateList(states, colors)
|
||||||
|
listOf(
|
||||||
|
binding.ivSkipNext, binding.ivSkipPrevious, binding.ivPlayMode, binding.ivTimer,
|
||||||
|
binding.ivChapter, binding.ivFastForward, binding.btnReset, binding.fabPlayStop
|
||||||
|
).forEach { btn ->
|
||||||
|
btn.setTextColor(stateList)
|
||||||
|
btn.iconTint = stateList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val oldBook: Book?
|
override val oldBook: Book?
|
||||||
get() = AudioPlay.book
|
get() = AudioPlay.book
|
||||||
|
|
||||||
@@ -488,3 +673,9 @@ class AudioPlayActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Int.copy(alpha: Float): Int {
|
||||||
|
val alpha = (alpha * 255).toInt()
|
||||||
|
return (this and 0x00FFFFFF) or (alpha shl 24)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,10 +1,17 @@
|
|||||||
package io.legato.kazusa.ui.book.info
|
package io.legato.kazusa.ui.book.info
|
||||||
|
|
||||||
|
import android.animation.ValueAnimator
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.RenderEffect
|
import android.graphics.RenderEffect
|
||||||
import android.graphics.Shader
|
import android.graphics.Shader
|
||||||
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.graphics.drawable.GradientDrawable
|
||||||
|
import android.graphics.drawable.TransitionDrawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -15,8 +22,12 @@ import android.widget.LinearLayout
|
|||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.graphics.scale
|
||||||
import androidx.core.view.doOnPreDraw
|
import androidx.core.view.doOnPreDraw
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.google.android.material.color.DynamicColors
|
||||||
|
import com.google.android.material.color.DynamicColorsOptions
|
||||||
|
import com.google.android.material.color.MaterialColors
|
||||||
import com.google.android.material.transition.platform.MaterialContainerTransform
|
import com.google.android.material.transition.platform.MaterialContainerTransform
|
||||||
import io.legato.kazusa.R
|
import io.legato.kazusa.R
|
||||||
import io.legato.kazusa.base.VMBaseActivity
|
import io.legato.kazusa.base.VMBaseActivity
|
||||||
@@ -75,7 +86,10 @@ import io.legato.kazusa.utils.startActivity
|
|||||||
import io.legato.kazusa.utils.toastOnUi
|
import io.legato.kazusa.utils.toastOnUi
|
||||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||||
import io.legato.kazusa.utils.visible
|
import io.legato.kazusa.utils.visible
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@@ -144,6 +158,13 @@ class BookInfoActivity :
|
|||||||
viewModel.refreshBook(book)
|
viewModel.refreshBook(book)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var surfaceFinalColor: Int = 0
|
||||||
|
private var secondaryFinalColor: Int = 0
|
||||||
|
private var onSurfaceFinalColor: Int = 0
|
||||||
|
private var secondaryContainerFinalColor: Int = 0
|
||||||
|
private var currentJob: Job? = null
|
||||||
|
private var wrappedContext: Context? = null
|
||||||
private var chapterChanged = false
|
private var chapterChanged = false
|
||||||
private val waitDialog by lazy { WaitDialog(this) }
|
private val waitDialog by lazy { WaitDialog(this) }
|
||||||
private var editMenuItem: MenuItem? = null
|
private var editMenuItem: MenuItem? = null
|
||||||
@@ -156,15 +177,26 @@ class BookInfoActivity :
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
postponeEnterTransition()
|
postponeEnterTransition()
|
||||||
val transform = MaterialContainerTransform().apply {
|
val transform = MaterialContainerTransform().apply {
|
||||||
addTarget(binding.ivCover)
|
addTarget(binding.cdCov)
|
||||||
scrimColor = Color.TRANSPARENT
|
scrimColor = Color.TRANSPARENT
|
||||||
}
|
}
|
||||||
window.sharedElementEnterTransition = transform
|
window.sharedElementEnterTransition = transform
|
||||||
window.sharedElementReturnTransition = transform
|
window.sharedElementReturnTransition = transform
|
||||||
window.sharedElementsUseOverlay = false
|
window.sharedElementsUseOverlay = false
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding.ivCover.transitionName = intent.getStringExtra("transitionName")
|
surfaceFinalColor =
|
||||||
binding.ivCover.doOnPreDraw {
|
MaterialColors.getColor(this, com.google.android.material.R.attr.colorSurface, -1)
|
||||||
|
secondaryFinalColor =
|
||||||
|
MaterialColors.getColor(this, com.google.android.material.R.attr.colorSecondary, -1)
|
||||||
|
onSurfaceFinalColor =
|
||||||
|
MaterialColors.getColor(this, com.google.android.material.R.attr.colorOnSurface, -1)
|
||||||
|
secondaryContainerFinalColor = MaterialColors.getColor(
|
||||||
|
this,
|
||||||
|
com.google.android.material.R.attr.colorSecondaryContainer,
|
||||||
|
-1
|
||||||
|
)
|
||||||
|
binding.cdCov.transitionName = intent.getStringExtra("transitionName")
|
||||||
|
binding.cdCov.doOnPreDraw {
|
||||||
startPostponedEnterTransition()
|
startPostponedEnterTransition()
|
||||||
}
|
}
|
||||||
setSupportActionBar(binding.topBar)
|
setSupportActionBar(binding.topBar)
|
||||||
@@ -342,6 +374,7 @@ class BookInfoActivity :
|
|||||||
|
|
||||||
private fun showBook(book: Book) = binding.run {
|
private fun showBook(book: Book) = binding.run {
|
||||||
showCover(book)
|
showCover(book)
|
||||||
|
addColorScheme(binding.ivCover.drawable)
|
||||||
tvName.text = book.name
|
tvName.text = book.name
|
||||||
tvAuthor.text = getString(R.string.author_show, book.getRealAuthor())
|
tvAuthor.text = getString(R.string.author_show, book.getRealAuthor())
|
||||||
tvOrigin.text = getString(R.string.origin_show, book.originName)
|
tvOrigin.text = getString(R.string.origin_show, book.originName)
|
||||||
@@ -377,7 +410,21 @@ class BookInfoActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun showCover(book: Book) {
|
private fun showCover(book: Book) {
|
||||||
binding.ivCover.load(book.getDisplayCover(), book.name, book.author, false, book.origin) {
|
binding.ivCover.load(
|
||||||
|
book.getDisplayCover(),
|
||||||
|
book.name,
|
||||||
|
book.author,
|
||||||
|
false,
|
||||||
|
book.origin,
|
||||||
|
onLoadFinish = {
|
||||||
|
binding.ivCover.post {
|
||||||
|
val drawable = binding.ivCover.drawable
|
||||||
|
if (drawable != null) {
|
||||||
|
addColorScheme(drawable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
if (!AppConfig.isEInkMode) {
|
if (!AppConfig.isEInkMode) {
|
||||||
//高版本使用RenderEffect
|
//高版本使用RenderEffect
|
||||||
BookCover.load(this, book.getDisplayCover(), false, book.origin)
|
BookCover.load(this, book.getDisplayCover(), false, book.origin)
|
||||||
@@ -392,7 +439,137 @@ class BookInfoActivity :
|
|||||||
.into(binding.bgBook)
|
.into(binding.bgBook)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addColorScheme(binding.ivCover.drawable)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addColorScheme(drawable: Drawable?) {
|
||||||
|
currentJob?.cancel()
|
||||||
|
currentJob = CoroutineScope(Dispatchers.Default).launch {
|
||||||
|
val bitmap = when (drawable) {
|
||||||
|
is BitmapDrawable -> drawable.bitmap
|
||||||
|
is TransitionDrawable -> (drawable.getDrawable(1) as? BitmapDrawable)?.bitmap
|
||||||
|
else -> null
|
||||||
|
} ?: return@launch
|
||||||
|
|
||||||
|
val colorAccuracy = true
|
||||||
|
val targetWidth = if (colorAccuracy) (bitmap.width / 4).coerceAtMost(256) else 16
|
||||||
|
val targetHeight = if (colorAccuracy) (bitmap.height / 4).coerceAtMost(256) else 16
|
||||||
|
val scaledBitmap = bitmap.scale(targetWidth, targetHeight, false)
|
||||||
|
|
||||||
|
val options = DynamicColorsOptions.Builder()
|
||||||
|
.setContentBasedSource(scaledBitmap)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
wrappedContext = DynamicColors.wrapContextIfAvailable(
|
||||||
|
this@BookInfoActivity,
|
||||||
|
options
|
||||||
|
).apply {
|
||||||
|
resources.configuration.uiMode =
|
||||||
|
this@BookInfoActivity.resources.configuration.uiMode
|
||||||
|
}
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
applyColorScheme()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun applyColorScheme() {
|
||||||
|
val ctx = wrappedContext ?: this
|
||||||
|
|
||||||
|
val colorPrimary = MaterialColors.getColor(ctx, androidx.appcompat.R.attr.colorPrimary, -1)
|
||||||
|
val colorSecondary =
|
||||||
|
MaterialColors.getColor(ctx, com.google.android.material.R.attr.colorSecondary, -1)
|
||||||
|
val colorTertiary =
|
||||||
|
MaterialColors.getColor(ctx, com.google.android.material.R.attr.colorTertiary, -1)
|
||||||
|
val colorOnSurface =
|
||||||
|
MaterialColors.getColor(ctx, com.google.android.material.R.attr.colorOnSurface, -1)
|
||||||
|
val colorSurface =
|
||||||
|
MaterialColors.getColor(ctx, com.google.android.material.R.attr.colorSurface, -1)
|
||||||
|
val colorSurfaceContainer = MaterialColors.getColor(
|
||||||
|
ctx,
|
||||||
|
com.google.android.material.R.attr.colorSurfaceContainer,
|
||||||
|
-1
|
||||||
|
)
|
||||||
|
val colorSecondaryContainer = MaterialColors.getColor(
|
||||||
|
ctx,
|
||||||
|
com.google.android.material.R.attr.colorSecondaryContainer,
|
||||||
|
-1
|
||||||
|
)
|
||||||
|
|
||||||
|
val surfaceTransition = ValueAnimator.ofArgb(surfaceFinalColor, colorSurface).apply {
|
||||||
|
duration = 400L
|
||||||
|
addUpdateListener { animation ->
|
||||||
|
val color = animation.animatedValue as Int
|
||||||
|
binding.cdInfo?.setCardBackgroundColor(color)
|
||||||
|
binding.llInfo.setBackgroundColor(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val buttonTransition = ValueAnimator.ofArgb(secondaryFinalColor, colorSecondary).apply {
|
||||||
|
duration = 400L
|
||||||
|
addUpdateListener { animation ->
|
||||||
|
val color = animation.animatedValue as Int
|
||||||
|
val tint = ColorStateList.valueOf(color)
|
||||||
|
listOf(
|
||||||
|
binding.btnShelf,
|
||||||
|
binding.tvTocView,
|
||||||
|
binding.tvChangeGroup,
|
||||||
|
binding.btnChangeSource
|
||||||
|
).forEach { btn ->
|
||||||
|
btn.setTextColor(color)
|
||||||
|
btn.iconTint = tint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val backTransition =
|
||||||
|
ValueAnimator.ofArgb(secondaryContainerFinalColor, colorSecondaryContainer).apply {
|
||||||
|
duration = 400L
|
||||||
|
addUpdateListener { animation ->
|
||||||
|
val color = animation.animatedValue as Int
|
||||||
|
binding.bgBookMask.setBackgroundColor(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val textTransition = ValueAnimator.ofArgb(onSurfaceFinalColor, colorOnSurface).apply {
|
||||||
|
duration = 400L
|
||||||
|
addUpdateListener { animation ->
|
||||||
|
val color = animation.animatedValue as Int
|
||||||
|
binding.tvName.setTextColor(color)
|
||||||
|
binding.tvAuthor.setTextColor(color)
|
||||||
|
binding.tvOrigin.setTextColor(color)
|
||||||
|
binding.tvDetail.setTextColor(color)
|
||||||
|
binding.ivName.imageTintList = ColorStateList.valueOf(color)
|
||||||
|
binding.ivWeb.imageTintList = ColorStateList.valueOf(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
surfaceTransition.start()
|
||||||
|
buttonTransition.start()
|
||||||
|
textTransition.start()
|
||||||
|
backTransition.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
surfaceFinalColor = colorSurface
|
||||||
|
secondaryFinalColor = colorSecondary
|
||||||
|
onSurfaceFinalColor = colorOnSurface
|
||||||
|
|
||||||
|
(binding.llCover.background as? GradientDrawable)?.colors =
|
||||||
|
intArrayOf(Color.TRANSPARENT, colorSurface)
|
||||||
|
|
||||||
|
binding.collTopBar.setContentScrimColor(colorSurfaceContainer)
|
||||||
|
binding.lbKind.applyColorScheme(colorSurfaceContainer, colorOnSurface)
|
||||||
|
binding.tvChapter.setTextColor(colorPrimary)
|
||||||
|
binding.div.setTextColor(colorSecondary)
|
||||||
|
binding.tvChapterIndex.setTextColor(colorSecondary)
|
||||||
|
binding.btnRead.setBackgroundColor(colorTertiary)
|
||||||
|
binding.tvToc.setTextColor(colorOnSurface)
|
||||||
|
binding.tvLasted.setTextColor(colorOnSurface)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun upLoading(isLoading: Boolean, chapterList: List<BookChapter>? = null) {
|
private fun upLoading(isLoading: Boolean, chapterList: List<BookChapter>? = null) {
|
||||||
|
|||||||
@@ -47,9 +47,20 @@ class LabelsBar @JvmOverloads constructor(
|
|||||||
usedChips.add(it)
|
usedChips.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
style(chip) // 在这里应用外部传入的样式
|
style(chip)
|
||||||
chip.text = label
|
chip.text = label
|
||||||
addView(chip)
|
addView(chip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun applyColorScheme(colorPrimaryContainer: Int, colorOnPrimaryContainer: Int) {
|
||||||
|
usedChips.forEach { chip ->
|
||||||
|
chip.chipBackgroundColor = ColorStateList.valueOf(colorPrimaryContainer)
|
||||||
|
chip.setTextColor(colorOnPrimaryContainer)
|
||||||
|
}
|
||||||
|
unUsedChips.forEach { chip ->
|
||||||
|
chip.chipBackgroundColor = ColorStateList.valueOf(colorPrimaryContainer)
|
||||||
|
chip.setTextColor(colorOnPrimaryContainer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -10,9 +10,16 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:contentDescription="@string/bg_image"
|
android:contentDescription="@string/bg_image"
|
||||||
android:foreground="@drawable/bg_book_mask_land"
|
|
||||||
android:scaleType="centerCrop" />
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/bg_book_mask"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:alpha="0.80"
|
||||||
|
android:background="@drawable/bg_gradient_mask"
|
||||||
|
android:contentDescription="@string/bg_image" />
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/app_bar"
|
android:id="@+id/app_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -21,6 +28,7 @@
|
|||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
|
android:id="@+id/coll_top_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="120dp"
|
android:layout_height="120dp"
|
||||||
style="?attr/collapsingToolbarLayoutLargeSize"
|
style="?attr/collapsingToolbarLayoutLargeSize"
|
||||||
@@ -58,128 +66,135 @@
|
|||||||
android:scrollbars="vertical">
|
android:scrollbars="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_cover"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:baselineAligned="false"
|
android:baselineAligned="false"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="3"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingHorizontal="32dp"
|
android:paddingHorizontal="32dp"
|
||||||
tools:ignore="RtlSymmetry">
|
tools:ignore="RtlSymmetry">
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/cd_cov"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginStart="32dp"
|
app:cardCornerRadius="8dp"
|
||||||
app:cardCornerRadius="16dp">
|
app:layout_constraintDimensionRatio="5:7"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.3"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintWidth_percent="0.5"
|
||||||
|
app:strokeWidth="0dp">
|
||||||
|
|
||||||
<io.legato.kazusa.ui.widget.image.CoverImageView
|
<io.legato.kazusa.ui.widget.image.CoverImageView
|
||||||
android:id="@+id/iv_cover"
|
android:id="@+id/iv_cover"
|
||||||
android:layout_width="150dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="210dp"
|
android:layout_height="match_parent"
|
||||||
android:contentDescription="@string/img_cover"
|
android:contentDescription="@string/img_cover"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:src="@drawable/image_cover_default" />
|
android:src="@drawable/image_cover_default" />
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingTop="16dp"
|
|
||||||
android:paddingHorizontal="30dp">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_name"
|
android:id="@+id/tv_name"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/book_name"
|
|
||||||
style="@style/TextAppearance.Material3.ActionBar.Title"
|
style="@style/TextAppearance.Material3.ActionBar.Title"
|
||||||
tools:ignore="RtlHardcoded" />
|
android:layout_width="0dp"
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:layout_marginTop="32dp"
|
||||||
android:orientation="horizontal"
|
android:text="@string/book_name"
|
||||||
android:paddingTop="6dp"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:paddingBottom="2dp"
|
app:layout_constraintStart_toStartOf="@id/cd_cov"
|
||||||
tools:ignore="UseCompoundDrawables">
|
app:layout_constraintTop_toBottomOf="@id/cd_cov" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
android:id="@+id/iv_name"
|
||||||
android:layout_width="18sp"
|
android:layout_width="18sp"
|
||||||
android:layout_height="18sp"
|
android:layout_height="18sp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
android:contentDescription="@string/author"
|
android:contentDescription="@string/author"
|
||||||
android:src="@drawable/ic_author"
|
android:src="@drawable/ic_author"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/cd_cov"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tv_name"
|
||||||
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_author"
|
android:id="@+id/tv_author"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_marginStart="4dp"
|
||||||
android:layout_marginStart="2dp"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="@string/author"
|
android:text="@string/author"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/iv_name"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/iv_name"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/iv_name"
|
||||||
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry" />
|
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry" />
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
tools:ignore="UseCompoundDrawables">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/iv_web"
|
android:id="@+id/iv_web"
|
||||||
android:layout_width="18sp"
|
android:layout_width="18sp"
|
||||||
android:layout_height="18sp"
|
android:layout_height="18sp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
android:contentDescription="@string/origin_format"
|
android:contentDescription="@string/origin_format"
|
||||||
android:src="@drawable/ic_web_outline"
|
android:src="@drawable/ic_web_outline"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/cd_cov"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/iv_name"
|
||||||
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_origin"
|
android:id="@+id/tv_origin"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_marginStart="2dp"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:paddingRight="6dp"
|
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry"
|
app:layout_constraintBottom_toBottomOf="@id/iv_web"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/iv_web"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/iv_web"
|
||||||
tools:text="@string/origin_format" />
|
tools:text="@string/origin_format" />
|
||||||
|
|
||||||
</LinearLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/ll_info"
|
android:id="@+id/cd_info"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="2"
|
android:layout_marginHorizontal="32dp"
|
||||||
|
android:layout_marginVertical="16dp"
|
||||||
|
android:layout_weight="5"
|
||||||
|
app:strokeWidth="0dp">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/ll_info"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="8dp"
|
||||||
android:background="@drawable/bg_gradient_mask_land"
|
android:background="@drawable/bg_gradient_mask_land"
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="8dp">
|
android:padding="8dp">
|
||||||
|
|
||||||
<HorizontalScrollView
|
<HorizontalScrollView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/scroll_labels"
|
||||||
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:scrollbars="none"
|
||||||
android:scrollbars="none">
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
<io.legato.kazusa.ui.widget.LabelsBar
|
<io.legato.kazusa.ui.widget.LabelsBar
|
||||||
android:id="@+id/lb_kind"
|
android:id="@+id/lb_kind"
|
||||||
@@ -189,171 +204,163 @@
|
|||||||
|
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|
||||||
<LinearLayout
|
<com.google.android.material.button.MaterialButtonGroup
|
||||||
|
android:id="@+id/cl_buttons"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
android:paddingHorizontal="8dp"
|
app:layout_constraintTop_toBottomOf="@id/scroll_labels">
|
||||||
android:paddingBottom="8dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/btn_shelf"
|
android:id="@+id/btn_shelf"
|
||||||
style="@style/Widget.Material3Expressive.Button.TonalButton"
|
style="@style/Widget.Material3Expressive.Button.TextButton"
|
||||||
android:backgroundTint="?attr/colorSurfaceContainer"
|
|
||||||
app:cornerRadius="16dp"
|
app:cornerRadius="16dp"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="6dp"
|
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:text="@string/remove_from_bookshelf"
|
android:text="@string/remove_from_bookshelf"
|
||||||
android:textSize="13sp"
|
android:textSize="13sp"
|
||||||
app:icon="@drawable/ic_clear_all"
|
app:icon="@drawable/ic_clear_all"
|
||||||
app:iconGravity="top"
|
app:iconGravity="top"
|
||||||
app:iconPadding="4dp"
|
app:iconPadding="4dp"
|
||||||
app:iconSize="20dp" />
|
app:iconSize="20dp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<!-- 查看目录按钮 -->
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/tv_toc_view"
|
android:id="@+id/tv_toc_view"
|
||||||
style="@style/Widget.Material3Expressive.Button.TonalButton"
|
style="@style/Widget.Material3Expressive.Button.TextButton"
|
||||||
android:backgroundTint="?attr/colorSurfaceContainer"
|
|
||||||
app:cornerRadius="16dp"
|
app:cornerRadius="16dp"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginHorizontal="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:text="@string/view_toc"
|
android:text="@string/view_toc"
|
||||||
android:textSize="13sp"
|
android:textSize="13sp"
|
||||||
app:icon="@drawable/ic_toc"
|
app:icon="@drawable/ic_toc"
|
||||||
app:iconGravity="top"
|
app:iconGravity="top"
|
||||||
app:iconPadding="4dp"
|
app:iconPadding="4dp"
|
||||||
app:iconSize="20dp" />
|
app:iconSize="20dp"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/btn_shelf"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/btn_shelf" />
|
||||||
|
|
||||||
<!-- 更换分组按钮 -->
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/tv_change_group"
|
android:id="@+id/tv_change_group"
|
||||||
style="@style/Widget.Material3Expressive.Button.TonalButton"
|
style="@style/Widget.Material3Expressive.Button.TextButton"
|
||||||
android:backgroundTint="?attr/colorSurfaceContainer"
|
|
||||||
app:cornerRadius="16dp"
|
app:cornerRadius="16dp"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginHorizontal="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:text="@string/change_group"
|
android:text="@string/change_group"
|
||||||
android:textSize="13sp"
|
android:textSize="13sp"
|
||||||
app:icon="@drawable/ic_groups"
|
app:icon="@drawable/ic_groups"
|
||||||
app:iconGravity="top"
|
app:iconGravity="top"
|
||||||
app:iconPadding="4dp"
|
app:iconPadding="4dp"
|
||||||
app:iconSize="20dp" />
|
app:iconSize="20dp"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/tv_toc_view"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/tv_toc_view" />
|
||||||
|
|
||||||
<!-- 更换来源按钮(保持原样) -->
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/btn_change_source"
|
android:id="@+id/btn_change_source"
|
||||||
style="@style/Widget.Material3Expressive.Button.TonalButton"
|
style="@style/Widget.Material3Expressive.Button.TextButton"
|
||||||
android:backgroundTint="?attr/colorSurfaceContainer"
|
|
||||||
app:cornerRadius="16dp"
|
app:cornerRadius="16dp"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:text="@string/book_source"
|
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
app:icon="@drawable/ic_change_source"
|
android:text="@string/book_source"
|
||||||
android:textSize="13sp"
|
android:textSize="13sp"
|
||||||
|
app:icon="@drawable/ic_change_source"
|
||||||
app:iconGravity="top"
|
app:iconGravity="top"
|
||||||
app:iconPadding="4dp"
|
app:iconPadding="4dp"
|
||||||
app:iconSize="20dp"
|
app:iconSize="20dp"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/tv_change_group"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/tv_change_group"
|
||||||
tools:contentDescription="@string/change_origin" />
|
tools:contentDescription="@string/change_origin" />
|
||||||
|
</com.google.android.material.button.MaterialButtonGroup>
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingVertical="16dp"
|
|
||||||
android:paddingHorizontal="2dp"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_toc"
|
android:id="@+id/tv_toc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingBottom="6dp"
|
android:layout_marginTop="8dp"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/cl_buttons"
|
||||||
tools:text="@string/toc_s" />
|
tools:text="@string/toc_s" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_lasted"
|
android:id="@+id/tv_lasted"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingBottom="6dp"
|
android:layout_marginTop="8dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tv_toc"
|
||||||
tools:text="@string/read_dur_progress" />
|
tools:text="@string/read_dur_progress" />
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_chapter"
|
android:id="@+id/tv_chapter"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="?attr/colorPrimary"
|
android:layout_marginTop="8dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:paddingEnd="8dp"
|
android:textColor="?attr/colorPrimary"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tv_lasted"
|
||||||
tools:text="@string/read_chapter_total" />
|
tools:text="@string/read_chapter_total" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/div"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
android:text="|"
|
android:text="|"
|
||||||
android:textColor="?attr/colorSecondary"
|
android:textColor="?attr/colorSecondary"
|
||||||
android:layout_marginEnd="8dp"/>
|
app:layout_constraintBaseline_toBaselineOf="@id/tv_chapter"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/tv_chapter" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_chapter_index"
|
android:id="@+id/tv_chapter_index"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="?attr/colorSecondary"
|
android:layout_marginStart="8dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
|
android:textColor="?attr/colorSecondary"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry"
|
app:layout_constraintBaseline_toBaselineOf="@id/tv_chapter"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/div"
|
||||||
tools:text="@string/read_chapter_index" />
|
tools:text="@string/read_chapter_index" />
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_detail"
|
android:id="@+id/tv_detail"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginHorizontal="8dp"
|
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
|
android:lineSpacingExtra="4dp"
|
||||||
android:minHeight="48dp"
|
android:minHeight="48dp"
|
||||||
android:paddingBottom="80dp"
|
android:paddingBottom="80dp"
|
||||||
android:lineSpacingExtra="4dp"
|
|
||||||
android:text="@string/book_intro"
|
android:text="@string/book_intro"
|
||||||
android:textIsSelectable="true"
|
android:textIsSelectable="true"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tv_chapter"
|
||||||
|
tools:text="@string/book_intro" />
|
||||||
|
|
||||||
</LinearLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
@@ -363,15 +370,13 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom|end"
|
android:layout_gravity="bottom|end"
|
||||||
android:layout_marginEnd="40dp"
|
android:layout_margin="48dp"
|
||||||
android:minWidth="0dp"
|
android:contentDescription="@string/reading"
|
||||||
android:layout_marginBottom="24dp"
|
android:minWidth="56dp"
|
||||||
android:text="@string/reading"
|
android:text="@string/reading"
|
||||||
android:textColor="?attr/colorOnPrimary"
|
android:textColor="?attr/colorOnPrimary"
|
||||||
android:contentDescription="@string/reading"
|
app:backgroundTint="?attr/colorTertiary"
|
||||||
app:iconGravity="textStart"
|
|
||||||
app:icon="@drawable/ic_bottom_books"
|
app:icon="@drawable/ic_bottom_books"
|
||||||
app:backgroundTint="?attr/colorSecondary"
|
|
||||||
app:iconTint="?attr/colorOnPrimary" />
|
app:iconTint="?attr/colorOnPrimary" />
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
@@ -14,16 +14,11 @@
|
|||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
tools:ignore="ContentDescription,ImageContrastCheck" />
|
tools:ignore="ContentDescription,ImageContrastCheck" />
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/vw_bg"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/vw_bg2"
|
android:id="@+id/vw_bg2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:alpha="0.80"
|
android:alpha="0.70"
|
||||||
android:background="?attr/colorSurfaceContainer" />
|
android:background="?attr/colorSurfaceContainer" />
|
||||||
|
|
||||||
<io.legato.kazusa.ui.widget.TitleBar
|
<io.legato.kazusa.ui.widget.TitleBar
|
||||||
@@ -194,8 +189,6 @@
|
|||||||
android:paddingHorizontal="6dp"
|
android:paddingHorizontal="6dp"
|
||||||
app:layout_constraintBottom_toTopOf="@id/ll_sub_menu">
|
app:layout_constraintBottom_toTopOf="@id/ll_sub_menu">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
|
|||||||
@@ -10,9 +10,16 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:contentDescription="@string/bg_image"
|
android:contentDescription="@string/bg_image"
|
||||||
android:foreground="@drawable/bg_book_mask"
|
|
||||||
android:scaleType="centerCrop" />
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/bg_book_mask"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:alpha="0.6"
|
||||||
|
android:background="?attr/colorSecondaryContainer"
|
||||||
|
android:contentDescription="@string/bg_image" />
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/app_bar"
|
android:id="@+id/app_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -21,6 +28,7 @@
|
|||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
|
android:id="@+id/coll_top_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
|
android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
|
||||||
style="?attr/collapsingToolbarLayoutMediumStyle"
|
style="?attr/collapsingToolbarLayoutMediumStyle"
|
||||||
@@ -56,32 +64,52 @@
|
|||||||
android:scrollbarStyle="outsideOverlay"
|
android:scrollbarStyle="outsideOverlay"
|
||||||
android:scrollbars="vertical">
|
android:scrollbars="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/ll_cover"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/bg_gradient_mask"
|
android:background="@drawable/bg_gradient_mask"
|
||||||
android:paddingHorizontal="16dp"
|
android:paddingHorizontal="16dp"
|
||||||
android:paddingVertical="8dp">
|
android:paddingVertical="8dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/cd_cov"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:cardCornerRadius="8dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintDimensionRatio="5:7"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintWidth_percent="0.32"
|
||||||
|
app:strokeWidth="0dp">
|
||||||
|
|
||||||
<io.legato.kazusa.ui.widget.image.CoverImageView
|
<io.legato.kazusa.ui.widget.image.CoverImageView
|
||||||
android:id="@+id/iv_cover"
|
android:id="@+id/iv_cover"
|
||||||
android:layout_width="100dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="140dp"
|
android:layout_height="match_parent"
|
||||||
android:contentDescription="@string/img_cover"
|
android:contentDescription="@string/img_cover"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:src="@drawable/image_cover_default" />
|
android:src="@drawable/image_cover_default" />
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="12dp">
|
android:padding="12dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/cd_cov"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/cd_cov"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/cd_cov">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_name"
|
android:id="@+id/tv_name"
|
||||||
@@ -102,6 +130,7 @@
|
|||||||
tools:ignore="UseCompoundDrawables">
|
tools:ignore="UseCompoundDrawables">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
android:id="@+id/iv_name"
|
||||||
android:layout_width="18sp"
|
android:layout_width="18sp"
|
||||||
android:layout_height="18sp"
|
android:layout_height="18sp"
|
||||||
android:contentDescription="@string/author"
|
android:contentDescription="@string/author"
|
||||||
@@ -152,20 +181,25 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/ll_info"
|
android:id="@+id/ll_info"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="0dp"
|
||||||
android:background="?attr/colorSurface"
|
android:background="?attr/colorSurface"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/ll_cover">
|
||||||
|
|
||||||
<HorizontalScrollView
|
<HorizontalScrollView
|
||||||
|
android:id="@+id/scroll_labels"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:scrollbars="none">
|
android:scrollbars="none"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
<io.legato.kazusa.ui.widget.LabelsBar
|
<io.legato.kazusa.ui.widget.LabelsBar
|
||||||
android:id="@+id/lb_kind"
|
android:id="@+id/lb_kind"
|
||||||
@@ -176,18 +210,14 @@
|
|||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/cl_buttons"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_marginHorizontal="8dp"
|
||||||
android:paddingBottom="8dp">
|
android:gravity="center_vertical"
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingHorizontal="8dp"
|
|
||||||
android:weightSum="4"
|
android:weightSum="4"
|
||||||
android:gravity="center_vertical">
|
app:layout_constraintTop_toBottomOf="@id/scroll_labels">
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/btn_shelf"
|
android:id="@+id/btn_shelf"
|
||||||
@@ -209,8 +239,8 @@
|
|||||||
style="@style/Widget.Material3Expressive.Button.TextButton"
|
style="@style/Widget.Material3Expressive.Button.TextButton"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginHorizontal="4dp"
|
android:layout_marginHorizontal="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:text="@string/view_toc"
|
android:text="@string/view_toc"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
@@ -242,99 +272,104 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/book_source"
|
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
app:icon="@drawable/ic_change_source"
|
android:text="@string/book_source"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
|
app:icon="@drawable/ic_change_source"
|
||||||
app:iconGravity="top"
|
app:iconGravity="top"
|
||||||
app:iconPadding="4dp"
|
app:iconPadding="4dp"
|
||||||
app:iconSize="20dp"
|
app:iconSize="20dp"
|
||||||
tools:contentDescription="@string/change_origin" />
|
tools:contentDescription="@string/change_origin" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingHorizontal="16dp"
|
|
||||||
android:paddingVertical="8dp"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_toc"
|
android:id="@+id/tv_toc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingBottom="6dp"
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/cl_buttons"
|
||||||
tools:text="@string/toc_s" />
|
tools:text="@string/toc_s" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_lasted"
|
android:id="@+id/tv_lasted"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingBottom="6dp"
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:singleLine="true"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tv_toc"
|
||||||
tools:text="@string/read_dur_progress" />
|
tools:text="@string/read_dur_progress" />
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_chapter"
|
android:id="@+id/tv_chapter"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="?attr/colorPrimaryVariant"
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:paddingEnd="8dp"
|
android:textColor="?attr/colorPrimary"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tv_lasted"
|
||||||
tools:text="@string/read_chapter_total" />
|
tools:text="@string/read_chapter_total" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/div"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
android:text="|"
|
android:text="|"
|
||||||
android:textColor="?attr/colorSecondary"
|
android:textColor="?attr/colorSecondary"
|
||||||
android:layout_marginEnd="8dp"/>
|
app:layout_constraintBaseline_toBaselineOf="@id/tv_chapter"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/tv_chapter" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_chapter_index"
|
android:id="@+id/tv_chapter_index"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="?attr/colorSecondary"
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
|
android:textColor="?attr/colorSecondary"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
tools:ignore="NestedWeights,RtlHardcoded,RtlSymmetry"
|
app:layout_constraintBaseline_toBaselineOf="@id/tv_chapter"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/div"
|
||||||
tools:text="@string/read_chapter_index" />
|
tools:text="@string/read_chapter_index" />
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_detail"
|
android:id="@+id/tv_detail"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:minHeight="48dp"
|
|
||||||
android:paddingHorizontal="16dp"
|
|
||||||
android:paddingBottom="80dp"
|
|
||||||
android:lineSpacingExtra="4dp"
|
android:lineSpacingExtra="4dp"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:paddingBottom="120dp"
|
||||||
android:text="@string/book_intro"
|
android:text="@string/book_intro"
|
||||||
android:textIsSelectable="true"
|
android:textIsSelectable="true"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tv_chapter"
|
||||||
|
tools:text="@string/book_intro" />
|
||||||
|
|
||||||
</LinearLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</LinearLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user