Update manga details list item

This commit is contained in:
Koitharu
2023-01-09 13:36:45 +02:00
parent 7f530d0476
commit 516470e8ae
18 changed files with 222 additions and 104 deletions

View File

@@ -1,7 +1,11 @@
package org.koitharu.kotatsu.list.ui
import android.os.Bundle
import android.view.*
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import androidx.annotation.CallSuper
import androidx.appcompat.view.ActionMode
@@ -15,7 +19,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import coil.ImageLoader
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import kotlinx.coroutines.launch
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.domain.reverseAsync
@@ -42,13 +45,23 @@ import org.koitharu.kotatsu.list.ui.adapter.MangaListListener
import org.koitharu.kotatsu.list.ui.model.ListHeader
import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.list.ui.model.MangaItemModel
import org.koitharu.kotatsu.main.ui.MainActivity
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
import org.koitharu.kotatsu.main.ui.owners.BottomNavOwner
import org.koitharu.kotatsu.main.ui.MainActivity
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaTag
import org.koitharu.kotatsu.reader.ui.ReaderActivity
import org.koitharu.kotatsu.search.ui.MangaListActivity
import org.koitharu.kotatsu.utils.ShareHelper
import org.koitharu.kotatsu.utils.ext.*
import org.koitharu.kotatsu.utils.ext.addMenuProvider
import org.koitharu.kotatsu.utils.ext.clearItemDecorations
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
import org.koitharu.kotatsu.utils.ext.getThemeColor
import org.koitharu.kotatsu.utils.ext.measureHeight
import org.koitharu.kotatsu.utils.ext.resolveDp
import org.koitharu.kotatsu.utils.ext.scaleUpActivityOptionsOf
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
import javax.inject.Inject
@AndroidEntryPoint
abstract class MangaListFragment :
@@ -138,6 +151,20 @@ abstract class MangaListFragment :
return selectionController?.onItemLongClick(item.id) ?: false
}
override fun onReadClick(manga: Manga, view: View) {
if (selectionController?.onItemClick(manga.id) != true) {
val intent = ReaderActivity.newIntent(context ?: return, manga)
startActivity(intent, scaleUpActivityOptionsOf(view).toBundle())
}
}
override fun onTagClick(manga: Manga, tag: MangaTag, view: View) {
if (selectionController?.onItemClick(manga.id) != true) {
val intent = MangaListActivity.newIntent(context ?: return, setOf(tag))
startActivity(intent)
}
}
@CallSuper
override fun onRefresh() {
binding.swipeRefreshLayout.isRefreshing = true
@@ -251,12 +278,14 @@ abstract class MangaListFragment :
)
addItemDecoration(decoration)
}
ListMode.DETAILED_LIST -> {
layoutManager = FitHeightLinearLayoutManager(context)
val spacing = resources.getDimensionPixelOffset(R.dimen.list_spacing)
updatePadding(left = spacing, right = spacing)
addItemDecoration(SpacingItemDecoration(spacing))
}
ListMode.GRID -> {
layoutManager = FitHeightGridLayoutManager(context, checkNotNull(spanResolver).spanCount).also {
it.spanSizeLookup = spanSizeLookup
@@ -284,21 +313,25 @@ abstract class MangaListFragment :
selectionController?.addAll(ids)
true
}
R.id.action_share -> {
ShareHelper(requireContext()).shareMangaLinks(selectedItems)
mode.finish()
true
}
R.id.action_favourite -> {
FavouriteCategoriesBottomSheet.show(childFragmentManager, selectedItems)
mode.finish()
true
}
R.id.action_save -> {
DownloadService.confirmAndStart(requireContext(), selectedItems)
mode.finish()
true
}
else -> false
}
}

View File

@@ -22,11 +22,12 @@ open class MangaSelectionDecoration(context: Context) : AbstractSelectionItemDec
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.grid_spacing_outer)
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 fillColor = ColorUtils.setAlphaComponent(
ColorUtils.blendARGB(strokeColor, context.getThemeColor(materialR.attr.colorSurface), 0.8f),
0x74
0x74,
)
protected val defaultRadius = context.resources.getDimension(R.dimen.list_selector_corner)
@@ -65,11 +66,11 @@ open class MangaSelectionDecoration(context: Context) : AbstractSelectionItemDec
setBounds(
(bounds.left + iconOffset).toInt(),
(bounds.top + iconOffset).toInt(),
(bounds.left + iconOffset + intrinsicWidth).toInt(),
(bounds.top + iconOffset + intrinsicHeight).toInt(),
(bounds.left + iconOffset + iconSize).toInt(),
(bounds.top + iconOffset + iconSize).toInt(),
)
draw(canvas)
}
}
}
}
}

View File

@@ -0,0 +1,13 @@
package org.koitharu.kotatsu.list.ui.adapter
import android.view.View
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaTag
interface MangaDetailsClickListener : OnListItemClickListener<Manga> {
fun onReadClick(manga: Manga, view: View)
fun onTagClick(manga: Manga, tag: MangaTag, view: View)
}

View File

@@ -1,34 +1,52 @@
package org.koitharu.kotatsu.list.ui.adapter
import android.view.View
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleOwner
import coil.ImageLoader
import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.chip.Chip
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
import org.koitharu.kotatsu.databinding.ItemMangaListDetailsBinding
import org.koitharu.kotatsu.history.domain.PROGRESS_NONE
import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.list.ui.model.MangaListDetailedModel
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.utils.ext.*
import org.koitharu.kotatsu.parsers.model.MangaTag
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
import org.koitharu.kotatsu.utils.ext.enqueueWith
import org.koitharu.kotatsu.utils.ext.newImageRequest
import org.koitharu.kotatsu.utils.ext.referer
import org.koitharu.kotatsu.utils.ext.textAndVisible
import org.koitharu.kotatsu.utils.image.CoverSizeResolver
fun mangaListDetailedItemAD(
coil: ImageLoader,
lifecycleOwner: LifecycleOwner,
clickListener: OnListItemClickListener<Manga>,
clickListener: MangaDetailsClickListener,
) = adapterDelegateViewBinding<MangaListDetailedModel, ListModel, ItemMangaListDetailsBinding>(
{ inflater, parent -> ItemMangaListDetailsBinding.inflate(inflater, parent, false) },
) {
var badge: BadgeDrawable? = null
itemView.setOnClickListener {
clickListener.onItemClick(item.manga, it)
}
itemView.setOnLongClickListener {
clickListener.onItemLongClick(item.manga, it)
val listenerAdapter = object : View.OnClickListener, View.OnLongClickListener, ChipsView.OnChipClickListener {
override fun onClick(v: View) = when (v.id) {
R.id.button_read -> clickListener.onReadClick(item.manga, v)
else -> clickListener.onItemClick(item.manga, v)
}
override fun onLongClick(v: View): Boolean = clickListener.onItemLongClick(item.manga, v)
override fun onChipClick(chip: Chip, data: Any?) {
val tag = data as? MangaTag ?: return
clickListener.onTagClick(item.manga, tag, chip)
}
}
itemView.setOnClickListener(listenerAdapter)
itemView.setOnLongClickListener(listenerAdapter)
binding.buttonRead.setOnClickListener(listenerAdapter)
binding.chipsTags.onChipClickListener = listenerAdapter
bind { payloads ->
binding.textViewTitle.text = item.title
@@ -44,8 +62,9 @@ fun mangaListDetailedItemAD(
lifecycle(lifecycleOwner)
enqueueWith(coil)
}
binding.textViewRating.textAndVisible = item.rating
binding.textViewTags.text = item.tags
binding.chipsTags.setChips(item.tags)
binding.ratingBar.isVisible = item.manga.hasRating
binding.ratingBar.rating = binding.ratingBar.numStars * item.manga.rating
badge = itemView.bindBadge(badge, item.counter)
}

View File

@@ -1,11 +1,9 @@
package org.koitharu.kotatsu.list.ui.adapter
import android.view.View
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaTag
interface MangaListListener : OnListItemClickListener<Manga>, ListStateHolderListener, ListHeaderClickListener {
interface MangaListListener : MangaDetailsClickListener, ListStateHolderListener, ListHeaderClickListener {
fun onUpdateFilter(tags: Set<MangaTag>)

View File

@@ -1,8 +1,7 @@
package org.koitharu.kotatsu.list.ui.model
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
import org.koitharu.kotatsu.core.prefs.ListMode
@@ -11,6 +10,8 @@ import org.koitharu.kotatsu.list.domain.ListExtraProvider
import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.utils.ext.ifZero
import java.net.SocketTimeoutException
import java.net.UnknownHostException
fun Manga.toListModel(counter: Int, progress: Float) = MangaListModel(
id = id,
@@ -26,12 +27,11 @@ fun Manga.toListDetailedModel(counter: Int, progress: Float) = MangaListDetailed
id = id,
title = title,
subtitle = altTitle,
rating = if (hasRating) String.format("%.1f", rating * 5) else null,
tags = tags.joinToString(", ") { it.title },
coverUrl = coverUrl,
manga = this,
counter = counter,
progress = progress,
tags = tags.map { ChipsView.ChipModel(0, it.title, false, false, it) },
)
fun Manga.toGridModel(counter: Int, progress: Float) = MangaGridModel(
@@ -69,9 +69,11 @@ suspend fun <C : MutableCollection<in MangaItemModel>> List<Manga>.toUi(
ListMode.LIST -> mapTo(destination) {
it.toListModel(extraProvider.getCounter(it.id), extraProvider.getProgress(it.id))
}
ListMode.DETAILED_LIST -> mapTo(destination) {
it.toListDetailedModel(extraProvider.getCounter(it.id), extraProvider.getProgress(it.id))
}
ListMode.GRID -> mapTo(destination) {
it.toGridModel(extraProvider.getCounter(it.id), extraProvider.getProgress(it.id))
}
@@ -95,5 +97,6 @@ private fun getErrorIcon(error: Throwable) = when (error) {
is UnknownHostException,
is SocketTimeoutException,
-> R.drawable.ic_plug_large
else -> R.drawable.ic_error_large
}

View File

@@ -1,15 +1,15 @@
package org.koitharu.kotatsu.list.ui.model
import org.koitharu.kotatsu.base.ui.widgets.ChipsView
import org.koitharu.kotatsu.parsers.model.Manga
data class MangaListDetailedModel(
override val id: Long,
override val title: String,
val subtitle: String?,
val tags: String,
override val coverUrl: String,
val rating: String?,
override val manga: Manga,
override val counter: Int,
override val progress: Float,
) : MangaItemModel
val tags: List<ChipsView.ChipModel>,
) : MangaItemModel

View File

@@ -12,7 +12,6 @@ import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import coil.ImageLoader
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.BaseActivity
import org.koitharu.kotatsu.base.ui.list.ListSelectionController
@@ -27,11 +26,15 @@ import org.koitharu.kotatsu.list.ui.adapter.MangaListListener
import org.koitharu.kotatsu.list.ui.model.ListHeader
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaTag
import org.koitharu.kotatsu.reader.ui.ReaderActivity
import org.koitharu.kotatsu.search.ui.MangaListActivity
import org.koitharu.kotatsu.search.ui.SearchActivity
import org.koitharu.kotatsu.search.ui.multi.adapter.MultiSearchAdapter
import org.koitharu.kotatsu.utils.ShareHelper
import org.koitharu.kotatsu.utils.ext.assistedViewModels
import org.koitharu.kotatsu.utils.ext.invalidateNestedItemDecorations
import org.koitharu.kotatsu.utils.ext.scaleUpActivityOptionsOf
import javax.inject.Inject
@AndroidEntryPoint
class MultiSearchActivity :
@@ -110,6 +113,20 @@ class MultiSearchActivity :
return selectionController.onItemLongClick(item.id)
}
override fun onReadClick(manga: Manga, view: View) {
if (!selectionController.onItemClick(manga.id)) {
val intent = ReaderActivity.newIntent(this, manga)
startActivity(intent, scaleUpActivityOptionsOf(view).toBundle())
}
}
override fun onTagClick(manga: Manga, tag: MangaTag, view: View) {
if (!selectionController.onItemClick(manga.id)) {
val intent = MangaListActivity.newIntent(this, setOf(tag))
startActivity(intent)
}
}
override fun onRetryClick(error: Throwable) {
viewModel.doSearch(viewModel.query.value.orEmpty())
}
@@ -139,16 +156,19 @@ class MultiSearchActivity :
mode.finish()
true
}
R.id.action_favourite -> {
FavouriteCategoriesBottomSheet.show(supportFragmentManager, collectSelectedItems())
mode.finish()
true
}
R.id.action_save -> {
DownloadService.confirmAndStart(this, collectSelectedItems())
mode.finish()
true
}
else -> false
}
}

View File

@@ -144,6 +144,10 @@ class FeedFragment :
startActivity(DetailsActivity.newIntent(context ?: return, item))
}
override fun onReadClick(manga: Manga, view: View) = Unit
override fun onTagClick(manga: Manga, tag: MangaTag, view: View) = Unit
companion object {
fun newInstance() = FeedFragment()

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/selector_overlay">
<item>
<shape android:shape="oval">
<solid android:color="?colorSurface" />
</shape>
</item>
<item android:id="@android:id/mask">
<shape android:shape="oval">
<solid android:color="@color/selector_overlay" />
</shape>
</item>
</ripple>

View File

@@ -1,7 +1,7 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:width="18dp"
android:height="18dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">

View File

@@ -34,9 +34,9 @@
<org.koitharu.kotatsu.history.ui.util.ReadingProgressView
android:id="@+id/progressView"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="4dp"
android:layout_width="@dimen/card_indicator_size"
android:layout_height="@dimen/card_indicator_size"
android:layout_margin="@dimen/card_indicator_offset"
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
app:layout_constraintEnd_toEndOf="@id/imageView_cover" />

View File

@@ -34,9 +34,9 @@
<org.koitharu.kotatsu.history.ui.util.ReadingProgressView
android:id="@+id/progressView"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="4dp"
android:layout_width="@dimen/card_indicator_size"
android:layout_height="@dimen/card_indicator_size"
android:layout_margin="@dimen/card_indicator_offset"
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
app:layout_constraintEnd_toEndOf="@id/imageView_cover" />

View File

@@ -7,13 +7,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
app:cardCornerRadius="16dp">
app:cardCornerRadius="16dp"
tools:layout_width="140dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="4dp">
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
@@ -31,10 +31,10 @@
<org.koitharu.kotatsu.history.ui.util.ReadingProgressView
android:id="@+id/progressView"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_width="@dimen/card_indicator_size"
android:layout_height="@dimen/card_indicator_size"
android:layout_gravity="bottom|end"
android:layout_margin="4dp" />
android:layout_margin="@dimen/card_indicator_offset" />
</FrameLayout>
@@ -45,8 +45,7 @@
android:elegantTextHeight="false"
android:ellipsize="end"
android:lines="2"
android:paddingHorizontal="8dp"
android:paddingVertical="4dp"
android:padding="8dp"
android:textAppearance="?attr/textAppearanceTitleSmall"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintStart_toStartOf="parent"

View File

@@ -4,31 +4,29 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/manga_list_details_item_height"
android:layout_height="wrap_content"
app:cardCornerRadius="16dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="4dp">
android:layout_height="match_parent">
<org.koitharu.kotatsu.base.ui.widgets.CoverImageView
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/imageView_cover"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_width="98dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="13:18"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Kotatsu.Cover"
tools:src="@sample/covers" />
<org.koitharu.kotatsu.history.ui.util.ReadingProgressView
android:id="@+id/progressView"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="4dp"
android:layout_width="@dimen/card_indicator_size"
android:layout_height="@dimen/card_indicator_size"
android:layout_margin="@dimen/card_indicator_offset"
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
app:layout_constraintEnd_toEndOf="@id/imageView_cover" />
@@ -36,13 +34,13 @@
android:id="@+id/textView_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
android:ellipsize="end"
android:maxLines="2"
android:textAppearance="?attr/textAppearanceTitleMedium"
app:layout_constraintBottom_toTopOf="@+id/textView_subtitle"
android:textAppearance="?attr/textAppearanceTitleLarge"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView_cover"
app:layout_constraintTop_toTopOf="parent"
@@ -52,61 +50,68 @@
android:id="@+id/textView_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="12dp"
android:ellipsize="none"
android:gravity="center_vertical"
android:maxLines="2"
android:requiresFadingEdge="horizontal"
android:textAppearance="?attr/textAppearanceBodyMedium"
app:layout_constraintBottom_toTopOf="@+id/linearLayout"
android:textAppearance="?attr/textAppearanceSubtitle1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView_cover"
app:layout_constraintTop_toBottomOf="@+id/textView_title"
tools:text="@tools:sample/lorem/random" />
<LinearLayout
android:id="@+id/linearLayout"
<HorizontalScrollView
android:id="@+id/scrollView_tags"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="8dp"
android:baselineAligned="false"
android:clipChildren="false"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
android:scrollbars="none"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView_cover"
app:layout_constraintTop_toBottomOf="@+id/textView_subtitle">
app:layout_constraintTop_toBottomOf="@id/textView_subtitle"
app:layout_goneMarginTop="12dp">
<TextView
android:id="@+id/textView_tags"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="none"
android:gravity="center_vertical"
android:requiresFadingEdge="horizontal"
android:singleLine="true"
android:textAppearance="?attr/textAppearanceBodySmall"
tools:text="@sample/genres" />
<TextView
android:id="@+id/textView_rating"
<org.koitharu.kotatsu.base.ui.widgets.ChipsView
android:id="@+id/chips_tags"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="4dp"
android:elegantTextHeight="false"
android:gravity="center_vertical"
android:paddingStart="6dp"
android:singleLine="true"
android:textAppearance="?attr/textAppearanceBodySmall"
app:drawableEndCompat="@drawable/ic_star"
tools:ignore="RtlSymmetry"
tools:text="9.6" />
app:chipSpacingHorizontal="6dp"
app:chipSpacingVertical="6dp"
app:singleLine="true" />
</HorizontalScrollView>
</LinearLayout>
<RatingBar
android:id="@+id/ratingBar"
style="?android:ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isIndicator="true"
android:paddingVertical="8dp"
app:layout_constraintEnd_toEndOf="@id/imageView_cover"
app:layout_constraintStart_toStartOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/imageView_cover" />
<ImageView
android:id="@+id/button_read"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:background="@drawable/bg_circle_button"
android:contentDescription="@string/read"
android:scaleType="center"
android:src="@drawable/ic_read"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/scrollView_tags"
app:layout_constraintVertical_bias="1" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -17,10 +17,10 @@
<TextView
android:id="@+id/textView_number"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_width="@dimen/card_indicator_size"
android:layout_height="@dimen/card_indicator_size"
android:layout_gravity="bottom|end"
android:layout_margin="8dp"
android:layout_margin="@dimen/card_indicator_offset"
android:ellipsize="none"
android:gravity="center"
android:singleLine="true"

View File

@@ -40,6 +40,9 @@
<dimen name="bottom_sheet_handle_size_max">24dp</dimen>
<dimen name="dialog_radius">8dp</dimen>
<dimen name="card_indicator_size">32dp</dimen>
<dimen name="card_indicator_offset">8dp</dimen>
<dimen name="appwidget_corner_radius_inner">8dp</dimen>
<!-- FastScroller -->

View File

@@ -224,6 +224,11 @@
<item name="cornerSize">6dp</item>
</style>
<style name="ShapeAppearanceOverlay.Kotatsu.Circle" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
<!--Preferences-->
<style name="PreferenceThemeOverlay.Kotatsu">