Chapters list grouping

master
Koitharu 2 years ago
parent 1fe5095654
commit fb716d300e
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -72,7 +72,7 @@ abstract class BaseActivity<B : ViewBinding> :
onBackPressedDispatcher.addCallback(actionModeDelegate) onBackPressedDispatcher.addCallback(actionModeDelegate)
} }
override fun onNewIntent(intent: Intent?) { override fun onNewIntent(intent: Intent) {
putDataToExtras(intent) putDataToExtras(intent)
super.onNewIntent(intent) super.onNewIntent(intent)
} }

@ -0,0 +1,162 @@
package org.koitharu.kotatsu.core.ui.image
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.ColorFilter
import android.graphics.Outline
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PixelFormat
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.os.Build
import androidx.annotation.ReturnThis
import org.koitharu.kotatsu.core.util.ext.getThemeColorStateList
import org.koitharu.kotatsu.core.util.ext.resolveDp
import org.koitharu.kotatsu.parsers.util.toIntUp
import com.google.android.material.R as materialR
class CardDrawable(
context: Context,
private var corners: Int,
) : Drawable() {
private val cornerSize = context.resources.resolveDp(12f)
private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
private val cornersF = FloatArray(8)
private val boundsF = RectF()
private val color: ColorStateList
private val path = Path()
private var alpha = 255
private var state: IntArray? = null
private var horizontalInset: Int = 0
init {
paint.style = Paint.Style.FILL
color = context.getThemeColorStateList(materialR.attr.colorSurfaceContainerHighest)
?: ColorStateList.valueOf(Color.TRANSPARENT)
setCorners(corners)
updateColor()
}
override fun draw(canvas: Canvas) {
canvas.drawPath(path, paint)
}
override fun setAlpha(alpha: Int) {
this.alpha = alpha
updateColor()
}
override fun setColorFilter(colorFilter: ColorFilter?) {
paint.colorFilter = colorFilter
}
override fun getColorFilter(): ColorFilter? = paint.colorFilter
override fun getOutline(outline: Outline) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
outline.setPath(path)
} else if (path.isConvex) {
outline.setConvexPath(path)
}
outline.alpha = 1f
}
override fun getPadding(padding: Rect): Boolean {
padding.set(
horizontalInset,
0,
horizontalInset,
0,
)
if (corners or TOP != 0) {
padding.top += cornerSize.toIntUp()
}
if (corners or BOTTOM != 0) {
padding.bottom += cornerSize.toIntUp()
}
return horizontalInset != 0
}
override fun onStateChange(state: IntArray): Boolean {
this.state = state
if (color.isStateful) {
updateColor()
return true
} else {
return false
}
}
@Deprecated("Deprecated in Java")
override fun getOpacity(): Int = PixelFormat.TRANSPARENT
override fun onBoundsChange(bounds: Rect) {
super.onBoundsChange(bounds)
boundsF.set(bounds)
boundsF.inset(horizontalInset.toFloat(), 0f)
path.reset()
path.addRoundRect(boundsF, cornersF, Path.Direction.CW)
path.close()
}
@ReturnThis
fun setCorners(corners: Int): CardDrawable {
this.corners = corners
val topLeft = if (corners and TOP_LEFT == TOP_LEFT) cornerSize else 0f
val topRight = if (corners and TOP_RIGHT == TOP_RIGHT) cornerSize else 0f
val bottomRight = if (corners and BOTTOM_RIGHT == BOTTOM_RIGHT) cornerSize else 0f
val bottomLeft = if (corners and BOTTOM_LEFT == BOTTOM_LEFT) cornerSize else 0f
cornersF[0] = topLeft
cornersF[1] = topLeft
cornersF[2] = topRight
cornersF[3] = topRight
cornersF[4] = bottomRight
cornersF[5] = bottomRight
cornersF[6] = bottomLeft
cornersF[7] = bottomLeft
invalidateSelf()
return this
}
fun setHorizontalInset(inset: Int) {
horizontalInset = inset
invalidateSelf()
}
private fun updateColor() {
paint.color = color.getColorForState(state, color.defaultColor)
paint.alpha = alpha
}
companion object {
const val TOP_LEFT = 1
const val TOP_RIGHT = 2
const val BOTTOM_LEFT = 4
const val BOTTOM_RIGHT = 8
const val LEFT = TOP_LEFT or BOTTOM_LEFT
const val TOP = TOP_LEFT or TOP_RIGHT
const val RIGHT = TOP_RIGHT or BOTTOM_RIGHT
const val BOTTOM = BOTTOM_LEFT or BOTTOM_RIGHT
const val NONE = 0
const val ALL = TOP_LEFT or TOP_RIGHT or BOTTOM_RIGHT or BOTTOM_LEFT
fun from(d: Drawable?): CardDrawable? = when (d) {
null -> null
is CardDrawable -> d
is LayerDrawable -> (0 until d.numberOfLayers).firstNotNullOfOrNull { i ->
from(d.getDrawable(i))
}
else -> null
}
}
}

@ -72,7 +72,8 @@ fun MangaDetails.mapChapters(
fun List<ChapterListItem>.withVolumeHeaders(context: Context): List<ListModel> { fun List<ChapterListItem>.withVolumeHeaders(context: Context): List<ListModel> {
var prevVolume = 0 var prevVolume = 0
val result = ArrayList<ListModel>((size * 1.4).toInt()) val result = ArrayList<ListModel>((size * 1.4).toInt())
for (item in this) { var groupPos: Byte = 0
for ((index, item) in this.withIndex()) {
val chapter = item.chapter val chapter = item.chapter
if (chapter.volume != prevVolume) { if (chapter.volume != prevVolume) {
val text = if (chapter.volume == 0) { val text = if (chapter.volume == 0) {
@ -82,8 +83,19 @@ fun List<ChapterListItem>.withVolumeHeaders(context: Context): List<ListModel> {
} }
result.add(ListHeader(text)) result.add(ListHeader(text))
prevVolume = chapter.volume prevVolume = chapter.volume
groupPos = ChapterListItem.GROUP_START
} else if (groupPos == ChapterListItem.GROUP_START) {
groupPos = ChapterListItem.GROUP_MIDDLE
} }
if (groupPos != 0.toByte()) {
val next = this.getOrNull(index + 1)
if (next == null || next.chapter.volume != prevVolume) {
groupPos = ChapterListItem.GROUP_END
}
result.add(item.copy(groupPosition = groupPos))
} else {
result.add(item) result.add(item)
} }
}
return result return result
} }

@ -13,13 +13,13 @@ import org.koitharu.kotatsu.core.util.ext.textAndVisible
import org.koitharu.kotatsu.databinding.ItemChapterBinding import org.koitharu.kotatsu.databinding.ItemChapterBinding
import org.koitharu.kotatsu.details.ui.model.ChapterListItem import org.koitharu.kotatsu.details.ui.model.ChapterListItem
import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.ListModel
import com.google.android.material.R as MR import com.google.android.material.R as materialR
fun chapterListItemAD( fun chapterListItemAD(
clickListener: OnListItemClickListener<ChapterListItem>, clickListener: OnListItemClickListener<ChapterListItem>,
) = adapterDelegateViewBinding<ChapterListItem, ListModel, ItemChapterBinding>( ) = adapterDelegateViewBinding<ChapterListItem, ListModel, ItemChapterBinding>(
viewBinding = { inflater, parent -> ItemChapterBinding.inflate(inflater, parent, false) }, viewBinding = { inflater, parent -> ItemChapterBinding.inflate(inflater, parent, false) },
on = { item, _, _ -> item is ChapterListItem && !item.isGrid } on = { item, _, _ -> item is ChapterListItem && !item.isGrid },
) { ) {
val eventListener = AdapterDelegateClickListenerAdapter(this, clickListener) val eventListener = AdapterDelegateClickListenerAdapter(this, clickListener)
@ -27,10 +27,17 @@ fun chapterListItemAD(
itemView.setOnLongClickListener(eventListener) itemView.setOnLongClickListener(eventListener)
bind { payloads -> bind { payloads ->
if (payloads.isEmpty()) {
binding.textViewTitle.text = item.chapter.name binding.textViewTitle.text = item.chapter.name
binding.textViewDescription.textAndVisible = item.description binding.textViewDescription.textAndVisible = item.description
} itemView.setBackgroundResource(
when {
item.isGroupStart && item.isGroupEnd -> R.drawable.bg_card_full
item.isGroupStart -> R.drawable.bg_card_top
item.isGroupMiddle -> R.drawable.bg_card_none
item.isGroupEnd -> R.drawable.bg_card_bottom
else -> R.drawable.list_selector
},
)
when { when {
item.isCurrent -> { item.isCurrent -> {
binding.textViewTitle.drawableStart = ContextCompat.getDrawable(context, R.drawable.ic_current_chapter) binding.textViewTitle.drawableStart = ContextCompat.getDrawable(context, R.drawable.ic_current_chapter)
@ -47,7 +54,7 @@ fun chapterListItemAD(
null null
} }
binding.textViewTitle.setTextColor(context.getThemeColorStateList(android.R.attr.textColorPrimary)) binding.textViewTitle.setTextColor(context.getThemeColorStateList(android.R.attr.textColorPrimary))
binding.textViewDescription.setTextColor(context.getThemeColorStateList(MR.attr.colorOutline)) binding.textViewDescription.setTextColor(context.getThemeColorStateList(materialR.attr.colorOutline))
binding.textViewTitle.typeface = Typeface.DEFAULT binding.textViewTitle.typeface = Typeface.DEFAULT
binding.textViewDescription.typeface = Typeface.DEFAULT binding.textViewDescription.typeface = Typeface.DEFAULT
} }

@ -7,7 +7,6 @@ import android.graphics.Paint
import android.graphics.RectF import android.graphics.RectF
import android.view.View import android.view.View
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@ -20,10 +19,7 @@ import com.google.android.material.R as materialR
class ChaptersSelectionDecoration(context: Context) : AbstractSelectionItemDecoration() { class ChaptersSelectionDecoration(context: Context) : AbstractSelectionItemDecoration() {
private val paint = Paint(Paint.ANTI_ALIAS_FLAG) private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
private val radius = context.resources.getDimension(materialR.dimen.abc_control_corner_material) private val defaultRadius = context.resources.getDimension(materialR.dimen.abc_control_corner_material)
private val checkIcon = ContextCompat.getDrawable(context, materialR.drawable.ic_mtrl_checked_circle)
private val iconOffset = context.resources.getDimensionPixelOffset(R.dimen.chapter_check_offset)
private val iconSize = context.resources.getDimensionPixelOffset(R.dimen.chapter_check_size)
private val strokeColor = context.getThemeColor(materialR.attr.colorPrimary, Color.RED) private val strokeColor = context.getThemeColor(materialR.attr.colorPrimary, Color.RED)
private val fillColor = ColorUtils.setAlphaComponent( private val fillColor = ColorUtils.setAlphaComponent(
ColorUtils.blendARGB(strokeColor, context.getThemeColor(materialR.attr.colorSurface), 0.8f), ColorUtils.blendARGB(strokeColor, context.getThemeColor(materialR.attr.colorSurface), 0.8f),
@ -36,12 +32,11 @@ class ChaptersSelectionDecoration(context: Context) : AbstractSelectionItemDecor
98, 98,
) )
paint.style = Paint.Style.FILL paint.style = Paint.Style.FILL
hasBackground = true hasBackground = false
hasForeground = true hasForeground = true
isIncludeDecorAndMargins = false isIncludeDecorAndMargins = false
paint.strokeWidth = context.resources.getDimension(R.dimen.selection_stroke_width) paint.strokeWidth = context.resources.getDimension(R.dimen.selection_stroke_width)
checkIcon?.setTint(strokeColor)
} }
override fun getItemId(parent: RecyclerView, child: View): Long { override fun getItemId(parent: RecyclerView, child: View): Long {
@ -50,19 +45,6 @@ class ChaptersSelectionDecoration(context: Context) : AbstractSelectionItemDecor
return item.chapter.id return item.chapter.id
} }
override fun onDrawBackground(
canvas: Canvas,
parent: RecyclerView,
child: View,
bounds: RectF,
state: RecyclerView.State,
) {
if (child is CardView) {
return
}
canvas.drawRoundRect(bounds, radius, radius, paint)
}
override fun onDrawForeground( override fun onDrawForeground(
canvas: Canvas, canvas: Canvas,
parent: RecyclerView, parent: RecyclerView,
@ -70,24 +52,16 @@ class ChaptersSelectionDecoration(context: Context) : AbstractSelectionItemDecor
bounds: RectF, bounds: RectF,
state: RecyclerView.State state: RecyclerView.State
) { ) {
if (child !is CardView) { val radius = if (child is CardView) {
return child.radius
} else {
defaultRadius
} }
val radius = child.radius
paint.color = fillColor paint.color = fillColor
paint.style = Paint.Style.FILL paint.style = Paint.Style.FILL
canvas.drawRoundRect(bounds, radius, radius, paint) canvas.drawRoundRect(bounds, radius, radius, paint)
paint.color = strokeColor paint.color = strokeColor
paint.style = Paint.Style.STROKE paint.style = Paint.Style.STROKE
canvas.drawRoundRect(bounds, radius, radius, paint) canvas.drawRoundRect(bounds, radius, radius, paint)
checkIcon?.run {
setBounds(
(bounds.right - iconSize - iconOffset).toInt(),
(bounds.top + iconOffset).toInt(),
(bounds.right - iconOffset).toInt(),
(bounds.top + iconOffset + iconSize).toInt(),
)
draw(canvas)
}
} }
} }

@ -5,11 +5,13 @@ import org.jsoup.internal.StringUtil.StringJoiner
import org.koitharu.kotatsu.core.model.formatNumber import org.koitharu.kotatsu.core.model.formatNumber
import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaChapter
import kotlin.experimental.and
data class ChapterListItem( data class ChapterListItem(
val chapter: MangaChapter, val chapter: MangaChapter,
val flags: Int, val flags: Byte,
private val uploadDateMs: Long, private val uploadDateMs: Long,
private val groupPosition: Byte,
) : ListModel { ) : ListModel {
var description: String? = null var description: String? = null
@ -51,6 +53,15 @@ data class ChapterListItem(
val isGrid: Boolean val isGrid: Boolean
get() = hasFlag(FLAG_GRID) get() = hasFlag(FLAG_GRID)
val isGroupStart: Boolean
get() = (groupPosition and GROUP_START) == GROUP_START
val isGroupMiddle: Boolean
get() = (groupPosition and GROUP_MIDDLE) == GROUP_MIDDLE
val isGroupEnd: Boolean
get() = (groupPosition and GROUP_END) == GROUP_END
private fun buildDescription(): String { private fun buildDescription(): String {
val joiner = StringJoiner("") val joiner = StringJoiner("")
chapter.formatNumber()?.let { chapter.formatNumber()?.let {
@ -67,7 +78,7 @@ data class ChapterListItem(
return joiner.complete() return joiner.complete()
} }
private fun hasFlag(flag: Int): Boolean { private fun hasFlag(flag: Byte): Boolean {
return (flags and flag) == flag return (flags and flag) == flag
} }
@ -88,11 +99,15 @@ data class ChapterListItem(
companion object { companion object {
const val FLAG_UNREAD = 2 const val FLAG_UNREAD: Byte = 2
const val FLAG_CURRENT = 4 const val FLAG_CURRENT: Byte = 4
const val FLAG_NEW = 8 const val FLAG_NEW: Byte = 8
const val FLAG_BOOKMARKED = 16 const val FLAG_BOOKMARKED: Byte = 16
const val FLAG_DOWNLOADED = 32 const val FLAG_DOWNLOADED: Byte = 32
const val FLAG_GRID = 64 const val FLAG_GRID: Byte = 64
const val GROUP_START: Byte = 2
const val GROUP_MIDDLE: Byte = 4
const val GROUP_END: Byte = 8
} }
} }

@ -7,6 +7,7 @@ import org.koitharu.kotatsu.details.ui.model.ChapterListItem.Companion.FLAG_GRID
import org.koitharu.kotatsu.details.ui.model.ChapterListItem.Companion.FLAG_NEW import org.koitharu.kotatsu.details.ui.model.ChapterListItem.Companion.FLAG_NEW
import org.koitharu.kotatsu.details.ui.model.ChapterListItem.Companion.FLAG_UNREAD import org.koitharu.kotatsu.details.ui.model.ChapterListItem.Companion.FLAG_UNREAD
import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaChapter
import kotlin.experimental.or
fun MangaChapter.toListItem( fun MangaChapter.toListItem(
isCurrent: Boolean, isCurrent: Boolean,
@ -16,7 +17,7 @@ fun MangaChapter.toListItem(
isBookmarked: Boolean, isBookmarked: Boolean,
isGrid: Boolean, isGrid: Boolean,
): ChapterListItem { ): ChapterListItem {
var flags = 0 var flags: Byte = 0
if (isCurrent) flags = flags or FLAG_CURRENT if (isCurrent) flags = flags or FLAG_CURRENT
if (isUnread) flags = flags or FLAG_UNREAD if (isUnread) flags = flags or FLAG_UNREAD
if (isNew) flags = flags or FLAG_NEW if (isNew) flags = flags or FLAG_NEW
@ -27,5 +28,6 @@ fun MangaChapter.toListItem(
chapter = this, chapter = this,
flags = flags, flags = flags,
uploadDateMs = uploadDate, uploadDateMs = uploadDate,
groupPosition = 0,
) )
} }

@ -7,7 +7,6 @@ import android.graphics.Paint
import android.graphics.RectF import android.graphics.RectF
import android.view.View import android.view.View
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.NO_ID import androidx.recyclerview.widget.RecyclerView.NO_ID
@ -21,9 +20,6 @@ import com.google.android.material.R as materialR
open class MangaSelectionDecoration(context: Context) : AbstractSelectionItemDecoration() { open class MangaSelectionDecoration(context: Context) : AbstractSelectionItemDecoration() {
protected val paint = Paint(Paint.ANTI_ALIAS_FLAG) protected val paint = Paint(Paint.ANTI_ALIAS_FLAG)
protected val checkIcon = ContextCompat.getDrawable(context, materialR.drawable.ic_mtrl_checked_circle)
protected val iconOffset = context.resources.getDimensionPixelOffset(R.dimen.card_indicator_offset)
protected val iconSize = context.resources.getDimensionPixelOffset(R.dimen.card_indicator_size)
protected val strokeColor = context.getThemeColor(materialR.attr.colorPrimary, Color.RED) protected val strokeColor = context.getThemeColor(materialR.attr.colorPrimary, Color.RED)
protected val fillColor = ColorUtils.setAlphaComponent( protected val fillColor = ColorUtils.setAlphaComponent(
ColorUtils.blendARGB(strokeColor, context.getThemeColor(materialR.attr.colorSurface), 0.8f), ColorUtils.blendARGB(strokeColor, context.getThemeColor(materialR.attr.colorSurface), 0.8f),
@ -37,7 +33,6 @@ open class MangaSelectionDecoration(context: Context) : AbstractSelectionItemDec
isIncludeDecorAndMargins = false isIncludeDecorAndMargins = false
paint.strokeWidth = context.resources.getDimension(R.dimen.selection_stroke_width) paint.strokeWidth = context.resources.getDimension(R.dimen.selection_stroke_width)
checkIcon?.setTint(strokeColor)
} }
override fun getItemId(parent: RecyclerView, child: View): Long { override fun getItemId(parent: RecyclerView, child: View): Long {
@ -53,7 +48,6 @@ open class MangaSelectionDecoration(context: Context) : AbstractSelectionItemDec
bounds: RectF, bounds: RectF,
state: RecyclerView.State, state: RecyclerView.State,
) { ) {
val isCard = child is CardView
val radius = (child as? CardView)?.radius ?: defaultRadius val radius = (child as? CardView)?.radius ?: defaultRadius
paint.color = fillColor paint.color = fillColor
paint.style = Paint.Style.FILL paint.style = Paint.Style.FILL
@ -61,16 +55,5 @@ open class MangaSelectionDecoration(context: Context) : AbstractSelectionItemDec
paint.color = strokeColor paint.color = strokeColor
paint.style = Paint.Style.STROKE paint.style = Paint.Style.STROKE
canvas.drawRoundRect(bounds, radius, radius, paint) canvas.drawRoundRect(bounds, radius, radius, paint)
if (isCard) {
checkIcon?.run {
setBounds(
(bounds.left + iconOffset).toInt(),
(bounds.top + iconOffset).toInt(),
(bounds.left + iconOffset + iconSize).toInt(),
(bounds.top + iconOffset + iconSize).toInt(),
)
draw(canvas)
}
}
} }
} }

@ -65,7 +65,7 @@ class ScrobblerConfigActivity : BaseActivity<ActivityScrobblerConfigBinding>(),
processIntent(intent) processIntent(intent)
} }
override fun onNewIntent(intent: Intent?) { override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent) super.onNewIntent(intent)
if (intent != null) { if (intent != null) {
setIntent(intent) setIntent(intent)

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/selector_overlay">
<item
android:left="@dimen/list_spacing_large"
android:right="@dimen/list_spacing_large">
<shape android:shape="rectangle">
<solid android:color="?colorSurfaceContainerHighest" />
<corners
android:bottomLeftRadius="@dimen/m3_card_corner"
android:bottomRightRadius="@dimen/m3_card_corner" />
<padding
android:left="@dimen/list_spacing_small"
android:right="@dimen/list_spacing_small" />
</shape>
</item>
<item
android:id="@android:id/mask"
android:left="@dimen/list_spacing_large"
android:right="@dimen/list_spacing_large">
<shape android:shape="rectangle">
<solid android:color="@color/selector_overlay" />
<corners
android:bottomLeftRadius="@dimen/m3_card_corner"
android:bottomRightRadius="@dimen/m3_card_corner" />
</shape>
</item>
</ripple>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/selector_overlay">
<item
android:left="@dimen/list_spacing_large"
android:right="@dimen/list_spacing_large">
<shape android:shape="rectangle">
<solid android:color="?colorSurfaceContainerHighest" />
<corners android:radius="@dimen/m3_card_corner" />
<padding
android:left="@dimen/list_spacing_small"
android:right="@dimen/list_spacing_small" />
</shape>
</item>
<item
android:id="@android:id/mask"
android:left="@dimen/list_spacing_large"
android:right="@dimen/list_spacing_large">
<shape android:shape="rectangle">
<solid android:color="@color/selector_overlay" />
<corners android:radius="@dimen/m3_card_corner" />
</shape>
</item>
</ripple>

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/selector_overlay">
<item
android:left="@dimen/list_spacing_large"
android:right="@dimen/list_spacing_large">
<shape android:shape="rectangle">
<solid android:color="?colorSurfaceContainerHighest" />
<padding
android:left="@dimen/list_spacing_small"
android:right="@dimen/list_spacing_small" />
</shape>
</item>
<item
android:id="@android:id/mask"
android:left="@dimen/list_spacing_large"
android:right="@dimen/list_spacing_large">
<shape android:shape="rectangle">
<solid android:color="@color/selector_overlay" />
</shape>
</item>
</ripple>

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/selector_overlay">
<item
android:left="@dimen/list_spacing_large"
android:right="@dimen/list_spacing_large">
<shape android:shape="rectangle">
<solid android:color="?colorSurfaceContainerHighest" />
<corners
android:topLeftRadius="@dimen/m3_card_corner"
android:topRightRadius="@dimen/m3_card_corner" />
<padding
android:left="@dimen/list_spacing_small"
android:right="@dimen/list_spacing_small" />
</shape>
</item>
<item
android:id="@android:id/mask"
android:left="@dimen/list_spacing_large"
android:right="@dimen/list_spacing_large">
<shape android:shape="rectangle">
<solid android:color="@color/selector_overlay" />
<corners
android:topLeftRadius="@dimen/m3_card_corner"
android:topRightRadius="@dimen/m3_card_corner" />
</shape>
</item>
</ripple>

@ -72,6 +72,7 @@
<dimen name="fastscroll_scrollbar_padding_end">6dp</dimen> <dimen name="fastscroll_scrollbar_padding_end">6dp</dimen>
<dimen name="m3_side_sheet_width">400dp</dimen> <dimen name="m3_side_sheet_width">400dp</dimen>
<dimen name="m3_card_corner">12dp</dimen>
<dimen name="reader_scroll_delta_min">200dp</dimen> <dimen name="reader_scroll_delta_min">200dp</dimen>

Loading…
Cancel
Save