Misc improvements

This commit is contained in:
Koitharu
2024-11-13 12:53:58 +02:00
parent 609f2bd134
commit 19446db192
17 changed files with 808 additions and 752 deletions

View File

@@ -19,9 +19,6 @@ abstract class LifecycleAwareViewHolder(
init {
parentLifecycleOwner.lifecycle.addObserver(ParentLifecycleObserver())
if (parentLifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)) {
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
}
}
fun setIsCurrent(value: Boolean) {
@@ -29,6 +26,9 @@ abstract class LifecycleAwareViewHolder(
dispatchResumed()
}
@CallSuper
open fun onCreate() = lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
@CallSuper
open fun onStart() = lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START)
@@ -41,6 +41,9 @@ abstract class LifecycleAwareViewHolder(
@CallSuper
open fun onStop() = lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
@CallSuper
open fun onDestroy() = lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private fun dispatchResumed() {
val isParentResumed = parentLifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)
if (isCurrent && isParentResumed) {
@@ -60,28 +63,18 @@ abstract class LifecycleAwareViewHolder(
private inner class ParentLifecycleObserver : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
}
override fun onCreate(owner: LifecycleOwner) = this@LifecycleAwareViewHolder.onCreate()
override fun onStart(owner: LifecycleOwner) {
onStart()
}
override fun onStart(owner: LifecycleOwner) = this@LifecycleAwareViewHolder.onStart()
override fun onResume(owner: LifecycleOwner) {
dispatchResumed()
}
override fun onResume(owner: LifecycleOwner) = this@LifecycleAwareViewHolder.dispatchResumed()
override fun onPause(owner: LifecycleOwner) {
dispatchResumed()
}
override fun onPause(owner: LifecycleOwner) = this@LifecycleAwareViewHolder.dispatchResumed()
override fun onStop(owner: LifecycleOwner) {
onStop()
}
override fun onStop(owner: LifecycleOwner) = this@LifecycleAwareViewHolder.onStop()
override fun onDestroy(owner: LifecycleOwner) {
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
this@LifecycleAwareViewHolder.onDestroy()
owner.lifecycle.removeObserver(this)
}
}

View File

@@ -25,7 +25,7 @@ import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import coil3.ImageLoader
import coil3.request.ImageRequest
import coil3.request.SuccessResult
@@ -127,7 +127,7 @@ class DetailsActivity :
View.OnClickListener,
View.OnLongClickListener, PopupMenu.OnMenuItemClickListener, View.OnLayoutChangeListener,
ViewTreeObserver.OnDrawListener, ChipsView.OnChipClickListener, OnListItemClickListener<Bookmark>,
OnContextClickListenerCompat {
OnContextClickListenerCompat, SwipeRefreshLayout.OnRefreshListener {
@Inject
lateinit var shortcutManager: AppShortcutManager
@@ -165,6 +165,7 @@ class DetailsActivity :
viewBinding.infoLayout.chipSource.setOnClickListener(this)
viewBinding.infoLayout.chipSize.setOnClickListener(this)
viewBinding.textViewDescription.addOnLayoutChangeListener(this)
viewBinding.swipeRefreshLayout.setOnRefreshListener(this)
viewBinding.textViewDescription.viewTreeObserver.addOnDrawListener(this)
viewBinding.textViewDescription.movementMethod = LinkMovementMethodCompat.getInstance()
viewBinding.chipsTags.onChipClickListener = this
@@ -349,6 +350,10 @@ class DetailsActivity :
Toast.makeText(view.context, R.string.incognito_mode, Toast.LENGTH_SHORT).show()
}
override fun onRefresh() {
viewModel.reload()
}
override fun onDraw() {
viewBinding.run {
buttonDescriptionMore.isVisible = textViewDescription.maxLines == Int.MAX_VALUE ||
@@ -420,18 +425,7 @@ class DetailsActivity :
}
private fun onLoadingStateChanged(isLoading: Boolean) {
val button = viewBinding.buttonDownload ?: return
if (isLoading) {
button.setImageDrawable(
CircularProgressDrawable(this).also {
it.setStyle(CircularProgressDrawable.LARGE)
it.setColorSchemeColors(getThemeColor(materialR.attr.colorControlNormal))
it.start()
},
)
} else {
button.setImageResource(R.drawable.ic_download)
}
viewBinding.swipeRefreshLayout.isRefreshing = isLoading
}
private fun onScrobblingInfoChanged(scrobblings: List<ScrobblingInfo>) {

View File

@@ -44,7 +44,7 @@ interface ChaptersSelectMacro {
) : ChaptersSelectMacro {
override fun getChaptersIds(mangaId: Long, chapters: List<MangaChapter>): Set<Long> {
val result = ArraySet<Long>(chaptersCount)
val result = ArraySet<Long>(minOf(chaptersCount, chapters.size))
for (c in chapters) {
if (c.branch == branch) {
result.add(c.id)
@@ -72,7 +72,7 @@ interface ChaptersSelectMacro {
val currentChapterId = currentChaptersIds.getOrDefault(mangaId, chapters.first().id)
var branch: String? = null
var isAdding = false
val result = ArraySet<Long>(chaptersCount)
val result = ArraySet<Long>(minOf(chaptersCount, chapters.size))
for (c in chapters) {
if (!isAdding) {
if (c.id == currentChapterId) {

View File

@@ -122,6 +122,8 @@ abstract class HistoryDao : MangaQueryBuilder.ConditionCallback {
suspend fun deleteAfter(minDate: Long) = setDeletedAtAfter(minDate, System.currentTimeMillis())
suspend fun deleteNotFavorite() = setDeletedAtNotFavorite(System.currentTimeMillis())
suspend fun clear() = setDeletedAtAfter(0L, System.currentTimeMillis())
suspend fun update(entity: HistoryEntity) = update(
@@ -157,6 +159,9 @@ abstract class HistoryDao : MangaQueryBuilder.ConditionCallback {
@Query("UPDATE history SET deleted_at = :deletedAt WHERE created_at >= :minDate AND deleted_at = 0")
protected abstract suspend fun setDeletedAtAfter(minDate: Long, deletedAt: Long)
@Query("UPDATE history SET deleted_at = :deletedAt WHERE deleted_at = 0 AND NOT EXISTS(SELECT * FROM favourites WHERE history.manga_id = favourites.manga_id)")
protected abstract suspend fun setDeletedAtNotFavorite(deletedAt: Long)
@Transaction
@RawQuery(observedEntities = [HistoryEntity::class])
protected abstract fun observeAllImpl(query: SupportSQLiteQuery): Flow<List<HistoryWithManga>>

View File

@@ -164,6 +164,10 @@ class HistoryRepository @Inject constructor(
db.getHistoryDao().deleteAfter(minDate)
}
suspend fun deleteNotFavorite() {
db.getHistoryDao().deleteNotFavorite()
}
suspend fun delete(ids: Collection<Long>): ReversibleHandle {
db.withTransaction {
for (id in ids) {

View File

@@ -53,6 +53,7 @@ class HistoryListMenuProvider(
arrayOf(
context.getString(R.string.last_2_hours),
context.getString(R.string.today),
context.getString(R.string.not_in_favorites),
context.getString(R.string.clear_all_history),
),
selectionListener.selection,
@@ -61,13 +62,12 @@ class HistoryListMenuProvider(
setIcon(R.drawable.ic_delete_all)
setNegativeButton(android.R.string.cancel, null)
setPositiveButton(R.string.clear) { _, _ ->
val minDate = when (selectionListener.selection) {
0 -> Instant.now().minus(2, ChronoUnit.HOURS)
1 -> LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()
2 -> Instant.EPOCH
else -> return@setPositiveButton
when (selectionListener.selection) {
0 -> viewModel.clearHistory(Instant.now().minus(2, ChronoUnit.HOURS))
1 -> viewModel.clearHistory(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant())
2 -> viewModel.removeNotFavorite()
3 -> viewModel.clearHistory(null)
}
viewModel.clearHistory(minDate)
}
}.show()
}

View File

@@ -101,9 +101,9 @@ class HistoryListViewModel @Inject constructor(
override fun onRetry() = Unit
fun clearHistory(minDate: Instant) {
fun clearHistory(minDate: Instant?) {
launchJob(Dispatchers.Default) {
val stringRes = if (minDate <= Instant.EPOCH) {
val stringRes = if (minDate == null) {
repository.clear()
R.string.history_cleared
} else {
@@ -114,6 +114,13 @@ class HistoryListViewModel @Inject constructor(
}
}
fun removeNotFavorite() {
launchJob(Dispatchers.Default) {
repository.deleteNotFavorite()
onActionDone.call(ReversibleAction(R.string.removed_from_history, null))
}
}
fun removeFromHistory(ids: Set<Long>) {
if (ids.isEmpty()) {
return

View File

@@ -169,7 +169,7 @@ class ImageActivity : BaseActivity<ActivityImageBinding>(), ImageRequest.Listene
private fun setDrawable(drawable: Drawable?) {
if (drawable != null) {
view.setImage(ImageSource.Bitmap(drawable.toBitmap()))
view.setImage(ImageSource.bitmap(drawable.toBitmap()))
} else {
view.recycle()
}

View File

@@ -6,6 +6,7 @@ import android.graphics.Color
import android.graphics.Point
import android.graphics.Rect
import androidx.annotation.ColorInt
import androidx.collection.LruCache
import androidx.core.graphics.alpha
import androidx.core.graphics.blue
import androidx.core.graphics.get
@@ -28,38 +29,46 @@ import kotlin.math.abs
class EdgeDetector(private val context: Context) {
private val mutex = Mutex()
private val cache = LruCache<ImageSource, Rect>(CACHE_SIZE)
suspend fun getBounds(imageSource: ImageSource): Rect? = mutex.withLock {
withContext(Dispatchers.IO) {
val decoder = SkiaPooledImageRegionDecoder(Bitmap.Config.RGB_565)
try {
val size = runInterruptible {
decoder.init(context, imageSource)
}
val edges = coroutineScope {
listOf(
async { detectLeftRightEdge(decoder, size, isLeft = true) },
async { detectTopBottomEdge(decoder, size, isTop = true) },
async { detectLeftRightEdge(decoder, size, isLeft = false) },
async { detectTopBottomEdge(decoder, size, isTop = false) },
).awaitAll()
}
var hasEdges = false
for (edge in edges) {
if (edge > 0) {
hasEdges = true
} else if (edge < 0) {
return@withContext null
suspend fun getBounds(imageSource: ImageSource): Rect? {
cache[imageSource]?.let { rect ->
return if (rect.isEmpty) null else rect
}
return mutex.withLock {
withContext(Dispatchers.IO) {
val decoder = SkiaPooledImageRegionDecoder(Bitmap.Config.RGB_565)
try {
val size = runInterruptible {
decoder.init(context, imageSource)
}
val edges = coroutineScope {
listOf(
async { detectLeftRightEdge(decoder, size, isLeft = true) },
async { detectTopBottomEdge(decoder, size, isTop = true) },
async { detectLeftRightEdge(decoder, size, isLeft = false) },
async { detectTopBottomEdge(decoder, size, isTop = false) },
).awaitAll()
}
var hasEdges = false
for (edge in edges) {
if (edge > 0) {
hasEdges = true
} else if (edge < 0) {
return@withContext null
}
}
if (hasEdges) {
Rect(edges[0], edges[1], size.x - edges[2], size.y - edges[3])
} else {
null
}
} finally {
decoder.recycle()
}
if (hasEdges) {
Rect(edges[0], edges[1], size.x - edges[2], size.y - edges[3])
} else {
null
}
} finally {
decoder.recycle()
}
}.also {
cache.put(imageSource, it ?: EMPTY_RECT)
}
}
@@ -135,6 +144,8 @@ class EdgeDetector(private val context: Context) {
private const val BLOCK_SIZE = 100
private const val COLOR_TOLERANCE = 16
private const val CACHE_SIZE = 24
private val EMPTY_RECT = Rect(0, 0, 0, 0)
fun isColorTheSame(@ColorInt a: Int, @ColorInt b: Int, tolerance: Int): Boolean {
return abs(a.red - b.red) <= tolerance &&

View File

@@ -164,7 +164,7 @@ class PageLoader @Inject constructor(
}
suspend fun getTrimmedBounds(uri: Uri): Rect? = runCatchingCancellable {
edgeDetector.getBounds(ImageSource.Uri(uri))
edgeDetector.getBounds(ImageSource.uri(uri))
}.onFailure { error ->
error.printStackTraceDebug()
}.getOrNull()

View File

@@ -57,6 +57,11 @@ abstract class BasePageHolder<B : ViewBinding>(
protected abstract fun onBind(data: ReaderPage)
override fun onCreate() {
super.onCreate()
context.registerComponentCallbacks(delegate)
}
override fun onResume() {
super.onResume()
if (delegate.state == State.ERROR && !delegate.isLoading()) {
@@ -64,6 +69,11 @@ abstract class BasePageHolder<B : ViewBinding>(
}
}
override fun onDestroy() {
context.unregisterComponentCallbacks(delegate)
super.onDestroy()
}
@CallSuper
open fun onAttachedToWindow() {
delegate.onAttachedToWindow()

View File

@@ -1,9 +1,12 @@
package org.koitharu.kotatsu.reader.ui.pager
import android.content.ComponentCallbacks2
import android.content.res.Configuration
import android.graphics.Rect
import android.net.Uri
import androidx.lifecycle.Observer
import com.davemorrissey.labs.subscaleview.DefaultOnImageEventListener
import com.davemorrissey.labs.subscaleview.ImageSource
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -34,7 +37,7 @@ class PageHolderDelegate(
private val networkState: NetworkState,
private val exceptionResolver: ExceptionResolver,
private val isWebtoon: Boolean,
) : DefaultOnImageEventListener, Observer<ReaderSettings> {
) : DefaultOnImageEventListener, Observer<ReaderSettings>, ComponentCallbacks2 {
private val scope = loader.loaderScope + Dispatchers.Main.immediate
var state = State.EMPTY
@@ -99,7 +102,7 @@ class PageHolderDelegate(
fun reload() {
if (state == State.SHOWN) {
uri?.let {
callback.onImageReady(it, cachedBounds)
callback.onImageReady(it.toImageSource(cachedBounds))
}
}
}
@@ -135,6 +138,15 @@ class PageHolderDelegate(
callback.onConfigChanged()
}
override fun onConfigurationChanged(newConfig: Configuration) = Unit
@Suppress("OVERRIDE_DEPRECATION")
override fun onLowMemory() = Unit
override fun onTrimMemory(level: Int) {
callback.onTrimMemory()
}
private fun tryConvert(uri: Uri, e: Exception) {
val prevJob = job
job = scope.launch {
@@ -148,7 +160,7 @@ class PageHolderDelegate(
null
}
state = State.CONVERTED
callback.onImageReady(newUri, cachedBounds)
callback.onImageReady(newUri.toImageSource(cachedBounds))
} catch (ce: CancellationException) {
throw ce
} catch (e2: Throwable) {
@@ -181,7 +193,7 @@ class PageHolderDelegate(
} else {
null
}
callback.onImageReady(checkNotNull(uri), cachedBounds)
callback.onImageReady(checkNotNull(uri).toImageSource(cachedBounds))
} catch (e: CancellationException) {
throw e
} catch (e: Throwable) {
@@ -201,6 +213,15 @@ class PageHolderDelegate(
.onEach { callback.onProgressChanged((100 * it).toInt()) }
.launchIn(scope)
private fun Uri.toImageSource(bounds: Rect?): ImageSource {
val source = ImageSource.uri(this)
return if (bounds != null) {
source.region(bounds)
} else {
source
}
}
enum class State {
EMPTY, LOADING, LOADED, CONVERTING, CONVERTED, SHOWING, SHOWN, ERROR
}
@@ -211,7 +232,7 @@ class PageHolderDelegate(
fun onError(e: Throwable)
fun onImageReady(uri: Uri, bounds: Rect?)
fun onImageReady(source: ImageSource)
fun onImageShowing(settings: ReaderSettings)
@@ -220,5 +241,7 @@ class PageHolderDelegate(
fun onProgressChanged(progress: Int)
fun onConfigChanged()
fun onTrimMemory()
}
}

View File

@@ -2,8 +2,6 @@ package org.koitharu.kotatsu.reader.ui.pager.standard
import android.annotation.SuppressLint
import android.graphics.PointF
import android.graphics.Rect
import android.net.Uri
import android.view.View
import android.view.animation.DecelerateInterpolator
import androidx.core.view.isVisible
@@ -91,11 +89,7 @@ open class PageHolder(
}
}
override fun onImageReady(uri: Uri, bounds: Rect?) {
val source = ImageSource.Uri(uri)
if (bounds != null) {
source.region(bounds)
}
override fun onImageReady(source: ImageSource) {
binding.ssiv.setImage(source)
}
@@ -143,6 +137,10 @@ open class PageHolder(
bindingInfo.progressBar.hide()
}
override fun onTrimMemory() {
// TODO https://developer.android.com/topic/performance/memory
}
final override fun onClick(v: View) {
when (v.id) {
R.id.button_retry -> delegate.retry(boundData?.toMangaPage() ?: return, isFromUser = true)

View File

@@ -1,7 +1,5 @@
package org.koitharu.kotatsu.reader.ui.pager.webtoon
import android.graphics.Rect
import android.net.Uri
import android.view.View
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleOwner
@@ -91,11 +89,7 @@ class WebtoonHolder(
}
}
override fun onImageReady(uri: Uri, bounds: Rect?) {
val source = ImageSource.Uri(uri)
if (bounds != null) {
source.region(bounds)
}
override fun onImageReady(source: ImageSource) {
binding.ssiv.setImage(source)
}
@@ -117,6 +111,10 @@ class WebtoonHolder(
bindingInfo.progressBar.hide()
}
override fun onTrimMemory() {
// TODO
}
override fun onClick(v: View) {
when (v.id) {
R.id.button_retry -> delegate.retry(boundData?.toMangaPage() ?: return, isFromUser = true)

View File

@@ -31,361 +31,368 @@
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollView"
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipToPadding="false"
android:scrollIndicators="top"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/appbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/appbar">
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:clipToPadding="false"
android:scrollIndicators="top"
android:scrollbars="vertical">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/imageView_cover"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:background="?colorSecondaryContainer"
android:foreground="?selectableItemBackground"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="H,13:18"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.3"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Kotatsu.Cover"
tools:background="@tools:sample/backgrounds/scenic[5]"
tools:ignore="ContentDescription,UnusedAttribute" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView_nsfw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/card_indicator_offset"
android:background="@drawable/bg_chip"
android:backgroundTint="@color/warning"
android:gravity="center"
android:paddingHorizontal="4dp"
android:paddingVertical="2dp"
android:text="@string/nsfw"
android:textAlignment="center"
android:textAppearance="?textAppearanceLabelMedium"
android:textColor="?colorOnError"
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
app:layout_constraintEnd_toEndOf="@id/imageView_cover" />
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/imageView_cover"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:background="?colorSecondaryContainer"
android:foreground="?selectableItemBackground"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="H,13:18"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.3"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Kotatsu.Cover"
tools:background="@tools:sample/backgrounds/scenic[5]"
tools:ignore="ContentDescription,UnusedAttribute" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="5"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" />
<TextView
android:id="@+id/textView_nsfw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/card_indicator_offset"
android:background="@drawable/bg_chip"
android:backgroundTint="@color/warning"
android:gravity="center"
android:paddingHorizontal="4dp"
android:paddingVertical="2dp"
android:text="@string/nsfw"
android:textAlignment="center"
android:textAppearance="?textAppearanceLabelMedium"
android:textColor="?colorOnError"
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
app:layout_constraintEnd_toEndOf="@id/imageView_cover" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="3"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_title"
tools:text="@tools:sample/lorem[12]" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="5"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" />
<ImageView
android:id="@+id/imageView_state"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginVertical="0.5dp"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="@id/textView_state"
app:layout_constraintDimensionRatio="1"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="@id/textView_state"
tools:src="@drawable/ic_state_ongoing" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="3"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_title"
tools:text="@tools:sample/lorem[12]" />
<TextView
android:id="@+id/textView_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:labelFor="@id/imageView_state"
android:singleLine="true"
android:textColor="?colorTertiary"
android:textStyle="bold"
app:drawableTint="?colorTertiary"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/imageView_state"
app:layout_constraintTop_toBottomOf="@id/textView_subtitle"
tools:text="@string/state_ongoing" />
<ImageView
android:id="@+id/imageView_state"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginVertical="0.5dp"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="@id/textView_state"
app:layout_constraintDimensionRatio="1"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="@id/textView_state"
tools:src="@drawable/ic_state_ongoing" />
<RatingBar
android:id="@+id/rating_bar"
style="?ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:isIndicator="true"
android:max="1"
android:numStars="5"
android:stepSize="0.5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_state"
tools:rating="4" />
<TextView
android:id="@+id/textView_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:labelFor="@id/imageView_state"
android:singleLine="true"
android:textColor="?colorTertiary"
android:textStyle="bold"
app:drawableTint="?colorTertiary"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/imageView_state"
app:layout_constraintTop_toBottomOf="@id/textView_subtitle"
tools:text="@string/state_ongoing" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:barrierMargin="@dimen/margin_normal"
app:constraint_referenced_ids="imageView_cover,rating_bar" />
<RatingBar
android:id="@+id/rating_bar"
style="?ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:isIndicator="true"
android:max="1"
android:numStars="5"
android:stepSize="0.5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_state"
tools:rating="4" />
<include
android:id="@+id/info_layout"
layout="@layout/layout_details_chips"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/screen_padding"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_header" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:barrierMargin="@dimen/margin_normal"
app:constraint_referenced_ids="imageView_cover,rating_bar" />
<org.koitharu.kotatsu.core.ui.widgets.ProgressButton
android:id="@+id/button_read"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginHorizontal="@dimen/screen_padding"
android:layout_marginTop="@dimen/margin_normal"
android:foreground="?selectableItemBackground"
android:gravity="center"
android:paddingHorizontal="6dp"
android:paddingVertical="8dp"
android:textColor="?colorOnPrimaryContainer"
app:baseColor="?colorSecondaryContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/info_layout"
app:progressColor="?colorPrimary"
app:subtitleTextAppearance="?textAppearanceBodySmall"
app:titleTextAppearance="?textAppearanceButton"
tools:max="100"
tools:progress="40"
tools:subtitle="12 chapters"
tools:title="@string/read" />
<include
android:id="@+id/info_layout"
layout="@layout/layout_details_chips"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/screen_padding"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_header" />
<TextView
android:id="@+id/textView_description_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_normal"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/description"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_description_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_read" />
<org.koitharu.kotatsu.core.ui.widgets.ProgressButton
android:id="@+id/button_read"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginHorizontal="@dimen/screen_padding"
android:layout_marginTop="@dimen/margin_normal"
android:foreground="?selectableItemBackground"
android:gravity="center"
android:paddingHorizontal="6dp"
android:paddingVertical="8dp"
android:textColor="?colorOnPrimaryContainer"
app:baseColor="?colorSecondaryContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/info_layout"
app:progressColor="?colorPrimary"
app:subtitleTextAppearance="?textAppearanceBodySmall"
app:titleTextAppearance="?textAppearanceButton"
tools:max="100"
tools:progress="40"
tools:subtitle="12 chapters"
tools:title="@string/read" />
<Button
android:id="@+id/button_description_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/more"
app:layout_constraintBaseline_toBaselineOf="@id/textView_description_title"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/textView_description_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_normal"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/description"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_description_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_read" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_normal"
android:layout_marginTop="@dimen/margin_small"
android:layout_marginEnd="@dimen/margin_normal"
android:ellipsize="end"
android:lineSpacingMultiplier="1.2"
android:maxLines="@integer/details_description_lines"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_description_title"
tools:ignore="UnusedAttribute"
tools:text="@tools:sample/lorem/random" />
<Button
android:id="@+id/button_description_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/more"
app:layout_constraintBaseline_toBaselineOf="@id/textView_description_title"
app:layout_constraintEnd_toEndOf="parent" />
<org.koitharu.kotatsu.core.ui.widgets.ChipsView
android:id="@+id/chips_tags"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/screen_padding"
android:layout_marginTop="@dimen/margin_small"
app:chipSpacingHorizontal="6dp"
app:chipSpacingVertical="6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView_description" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_normal"
android:layout_marginTop="@dimen/margin_small"
android:layout_marginEnd="@dimen/margin_normal"
android:ellipsize="end"
android:lineSpacingMultiplier="1.2"
android:maxLines="@integer/details_description_lines"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_description_title"
tools:ignore="UnusedAttribute"
tools:text="@tools:sample/lorem/random" />
<TextView
android:id="@+id/textView_scrobbling_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_normal"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/tracking"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_scrobbling_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/chips_tags" />
<org.koitharu.kotatsu.core.ui.widgets.ChipsView
android:id="@+id/chips_tags"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/screen_padding"
android:layout_marginTop="@dimen/margin_small"
app:chipSpacingHorizontal="6dp"
app:chipSpacingVertical="6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView_description" />
<Button
android:id="@+id/button_scrobbling_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/manage"
app:layout_constraintBaseline_toBaselineOf="@id/textView_scrobbling_title"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/textView_scrobbling_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_normal"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/tracking"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_scrobbling_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/chips_tags" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView_scrobbling"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="12dp"
android:nestedScrollingEnabled="false"
android:orientation="vertical"
android:overScrollMode="never"
android:scrollbars="none"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_scrobbling_title"
tools:itemCount="2"
tools:listitem="@layout/item_scrobbling_info"
tools:visibility="visible" />
<Button
android:id="@+id/button_scrobbling_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/manage"
app:layout_constraintBaseline_toBaselineOf="@id/textView_scrobbling_title"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progressBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone"
app:hideAnimationBehavior="outward"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:showAnimationBehavior="inward"
app:trackCornerRadius="0dp"
tools:visibility="visible" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView_scrobbling"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="12dp"
android:nestedScrollingEnabled="false"
android:orientation="vertical"
android:overScrollMode="never"
android:scrollbars="none"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_scrobbling_title"
tools:itemCount="2"
tools:listitem="@layout/item_scrobbling_info"
tools:visibility="visible" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_scrobbling"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="recyclerView_scrobbling,textView_scrobbling_title,button_scrobbling_more"
tools:visibility="visible" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progressBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone"
app:hideAnimationBehavior="outward"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:showAnimationBehavior="inward"
app:trackCornerRadius="0dp"
tools:visibility="visible" />
<TextView
android:id="@+id/textView_related_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_small"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/related_manga"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_related_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/recyclerView_scrobbling" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_scrobbling"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="recyclerView_scrobbling,textView_scrobbling_title,button_scrobbling_more"
tools:visibility="visible" />
<Button
android:id="@+id/button_related_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/show_all"
android:visibility="gone"
app:layout_constraintBaseline_toBaselineOf="@id/textView_related_title"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/textView_related_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_small"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/related_manga"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_related_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/recyclerView_scrobbling" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView_related"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:clipToPadding="false"
android:nestedScrollingEnabled="false"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingEnd="12dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_related_title"
tools:listitem="@layout/item_manga_grid" />
<Button
android:id="@+id/button_related_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/show_all"
android:visibility="gone"
app:layout_constraintBaseline_toBaselineOf="@id/textView_related_title"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_related"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="recyclerView_related,textView_related_title,button_related_more"
tools:visibility="visible" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView_related"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:clipToPadding="false"
android:nestedScrollingEnabled="false"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingEnd="12dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_related_title"
tools:listitem="@layout/item_manga_grid" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.Group
android:id="@+id/group_related"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="recyclerView_related,textView_related_title,button_related_more"
tools:visibility="visible" />
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_chapters"

View File

@@ -26,375 +26,381 @@
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollView"
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:scrollIndicators="top"
android:scrollbars="vertical"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/details_bs_peek_height">
android:clipToPadding="false"
android:scrollIndicators="top"
android:scrollbars="vertical">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/imageView_cover"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:background="?colorSecondaryContainer"
android:foreground="?selectableItemBackground"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="H,13:18"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.3"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Kotatsu.Cover"
tools:background="@tools:sample/backgrounds/scenic[5]"
tools:ignore="ContentDescription,UnusedAttribute" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/details_bs_peek_height">
<TextView
android:id="@+id/textView_nsfw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/card_indicator_offset"
android:background="@drawable/bg_chip"
android:backgroundTint="@color/warning"
android:gravity="center"
android:paddingHorizontal="4dp"
android:paddingVertical="2dp"
android:text="@string/nsfw"
android:textAlignment="center"
android:textAppearance="?textAppearanceLabelMedium"
android:textColor="?colorOnError"
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
app:layout_constraintEnd_toEndOf="@id/imageView_cover" />
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/imageView_cover"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:background="?colorSecondaryContainer"
android:foreground="?selectableItemBackground"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="H,13:18"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.3"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Kotatsu.Cover"
tools:background="@tools:sample/backgrounds/scenic[5]"
tools:ignore="ContentDescription,UnusedAttribute" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="@integer/details_title_lines"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" />
<TextView
android:id="@+id/textView_nsfw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/card_indicator_offset"
android:background="@drawable/bg_chip"
android:backgroundTint="@color/warning"
android:gravity="center"
android:paddingHorizontal="4dp"
android:paddingVertical="2dp"
android:text="@string/nsfw"
android:textAlignment="center"
android:textAppearance="?textAppearanceLabelMedium"
android:textColor="?colorOnError"
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
app:layout_constraintEnd_toEndOf="@id/imageView_cover" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="3"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_title"
tools:text="@tools:sample/lorem[12]" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="@integer/details_title_lines"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" />
<ImageView
android:id="@+id/imageView_state"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginVertical="0.5dp"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="@id/textView_state"
app:layout_constraintDimensionRatio="1"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="@id/textView_state"
app:tint="?colorTertiary"
tools:src="@drawable/ic_state_ongoing" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="3"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_title"
tools:text="@tools:sample/lorem[12]" />
<TextView
android:id="@+id/textView_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:labelFor="@id/imageView_state"
android:singleLine="true"
android:textColor="?colorTertiary"
android:textStyle="bold"
app:drawableTint="?colorTertiary"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/imageView_state"
app:layout_constraintTop_toBottomOf="@id/textView_subtitle"
tools:text="@string/state_ongoing" />
<ImageView
android:id="@+id/imageView_state"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginVertical="0.5dp"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="@id/textView_state"
app:layout_constraintDimensionRatio="1"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="@id/textView_state"
app:tint="?colorTertiary"
tools:src="@drawable/ic_state_ongoing" />
<RatingBar
android:id="@+id/rating_bar"
style="?ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:isIndicator="true"
android:max="1"
android:numStars="5"
android:stepSize="0.5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_state"
tools:rating="4" />
<TextView
android:id="@+id/textView_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:labelFor="@id/imageView_state"
android:singleLine="true"
android:textColor="?colorTertiary"
android:textStyle="bold"
app:drawableTint="?colorTertiary"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/imageView_state"
app:layout_constraintTop_toBottomOf="@id/textView_subtitle"
tools:text="@string/state_ongoing" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:barrierMargin="@dimen/margin_normal"
app:constraint_referenced_ids="imageView_cover,rating_bar" />
<RatingBar
android:id="@+id/rating_bar"
style="?ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:isIndicator="true"
android:max="1"
android:numStars="5"
android:stepSize="0.5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_state"
tools:rating="4" />
<include
android:id="@+id/info_layout"
layout="@layout/layout_details_chips"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/screen_padding"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_header" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:barrierMargin="@dimen/margin_normal"
app:constraint_referenced_ids="imageView_cover,rating_bar" />
<org.koitharu.kotatsu.core.ui.widgets.ProgressButton
android:id="@+id/button_read"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="@dimen/margin_normal"
android:layout_marginEnd="12dp"
android:foreground="?selectableItemBackground"
android:gravity="center"
android:paddingHorizontal="6dp"
android:paddingVertical="8dp"
app:baseColor="?colorSecondaryContainer"
app:layout_constraintEnd_toStartOf="@id/button_download"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/info_layout"
app:progressColor="?colorPrimary"
app:subtitleTextAppearance="?textAppearanceBodySmall"
app:titleTextAppearance="?textAppearanceButton"
tools:max="100"
tools:progress="40"
tools:subtitle="12 chapters"
tools:title="@string/read" />
<include
android:id="@+id/info_layout"
layout="@layout/layout_details_chips"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/screen_padding"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_header" />
<ImageView
android:id="@+id/button_download"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_circle_button"
android:backgroundTint="?colorSecondaryContainer"
android:contentDescription="@string/download"
android:scaleType="centerInside"
app:layout_constraintBottom_toBottomOf="@id/button_read"
app:layout_constraintDimensionRatio="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/button_read"
app:srcCompat="@drawable/ic_download" />
<org.koitharu.kotatsu.core.ui.widgets.ProgressButton
android:id="@+id/button_read"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="@dimen/margin_normal"
android:layout_marginEnd="12dp"
android:foreground="?selectableItemBackground"
android:gravity="center"
android:paddingHorizontal="6dp"
android:paddingVertical="8dp"
app:baseColor="?colorSecondaryContainer"
app:layout_constraintEnd_toStartOf="@id/button_download"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/info_layout"
app:progressColor="?colorPrimary"
app:subtitleTextAppearance="?textAppearanceBodySmall"
app:titleTextAppearance="?textAppearanceButton"
tools:max="100"
tools:progress="40"
tools:subtitle="12 chapters"
tools:title="@string/read" />
<TextView
android:id="@+id/textView_description_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_normal"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/description"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_description_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_read" />
<ImageView
android:id="@+id/button_download"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_circle_button"
android:backgroundTint="?colorSecondaryContainer"
android:contentDescription="@string/download"
android:scaleType="centerInside"
app:layout_constraintBottom_toBottomOf="@id/button_read"
app:layout_constraintDimensionRatio="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/button_read"
app:srcCompat="@drawable/ic_download" />
<Button
android:id="@+id/button_description_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/more"
app:layout_constraintBaseline_toBaselineOf="@id/textView_description_title"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/textView_description_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_normal"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/description"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_description_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_read" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_normal"
android:layout_marginTop="@dimen/margin_small"
android:layout_marginEnd="@dimen/margin_normal"
android:ellipsize="end"
android:lineSpacingMultiplier="1.2"
android:maxLines="@integer/details_description_lines"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_description_title"
tools:ignore="UnusedAttribute"
tools:text="@tools:sample/lorem/random" />
<Button
android:id="@+id/button_description_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/more"
app:layout_constraintBaseline_toBaselineOf="@id/textView_description_title"
app:layout_constraintEnd_toEndOf="parent" />
<org.koitharu.kotatsu.core.ui.widgets.ChipsView
android:id="@+id/chips_tags"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/screen_padding"
android:layout_marginTop="@dimen/margin_normal"
app:chipSpacingHorizontal="6dp"
app:chipSpacingVertical="6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView_description" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_normal"
android:layout_marginTop="@dimen/margin_small"
android:layout_marginEnd="@dimen/margin_normal"
android:ellipsize="end"
android:lineSpacingMultiplier="1.2"
android:maxLines="@integer/details_description_lines"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_description_title"
tools:ignore="UnusedAttribute"
tools:text="@tools:sample/lorem/random" />
<TextView
android:id="@+id/textView_scrobbling_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_normal"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/tracking"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_scrobbling_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/chips_tags" />
<org.koitharu.kotatsu.core.ui.widgets.ChipsView
android:id="@+id/chips_tags"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/screen_padding"
android:layout_marginTop="@dimen/margin_normal"
app:chipSpacingHorizontal="6dp"
app:chipSpacingVertical="6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView_description" />
<Button
android:id="@+id/button_scrobbling_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/manage"
app:layout_constraintBaseline_toBaselineOf="@id/textView_scrobbling_title"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/textView_scrobbling_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_normal"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/tracking"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_scrobbling_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/chips_tags" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView_scrobbling"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="12dp"
android:nestedScrollingEnabled="false"
android:orientation="vertical"
android:overScrollMode="never"
android:scrollbars="none"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_scrobbling_title"
tools:itemCount="2"
tools:listitem="@layout/item_scrobbling_info"
tools:visibility="visible" />
<Button
android:id="@+id/button_scrobbling_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/manage"
app:layout_constraintBaseline_toBaselineOf="@id/textView_scrobbling_title"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progressBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone"
app:hideAnimationBehavior="outward"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:showAnimationBehavior="inward"
app:trackCornerRadius="0dp"
tools:visibility="visible" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView_scrobbling"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="12dp"
android:nestedScrollingEnabled="false"
android:orientation="vertical"
android:overScrollMode="never"
android:scrollbars="none"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_scrobbling_title"
tools:itemCount="2"
tools:listitem="@layout/item_scrobbling_info"
tools:visibility="visible" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_scrobbling"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="recyclerView_scrobbling,textView_scrobbling_title,button_scrobbling_more"
tools:visibility="visible" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progressBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone"
app:hideAnimationBehavior="outward"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:showAnimationBehavior="inward"
app:trackCornerRadius="0dp"
tools:visibility="visible" />
<TextView
android:id="@+id/textView_related_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_small"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/related_manga"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_related_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/recyclerView_scrobbling" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_scrobbling"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="recyclerView_scrobbling,textView_scrobbling_title,button_scrobbling_more"
tools:visibility="visible" />
<Button
android:id="@+id/button_related_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/show_all"
android:visibility="gone"
app:layout_constraintBaseline_toBaselineOf="@id/textView_related_title"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/textView_related_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_small"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:padding="@dimen/grid_spacing"
android:singleLine="true"
android:text="@string/related_manga"
android:textAppearance="?textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/button_related_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/recyclerView_scrobbling" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView_related"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:clipToPadding="false"
android:nestedScrollingEnabled="false"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingEnd="12dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_related_title"
tools:listitem="@layout/item_manga_grid" />
<Button
android:id="@+id/button_related_more"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/show_all"
android:visibility="gone"
app:layout_constraintBaseline_toBaselineOf="@id/textView_related_title"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_related"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="recyclerView_related,textView_related_title,button_related_more"
tools:visibility="visible" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView_related"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:clipToPadding="false"
android:nestedScrollingEnabled="false"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingEnd="12dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView_related_title"
tools:listitem="@layout/item_manga_grid" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.Group
android:id="@+id/group_related"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="recyclerView_related,textView_related_title,button_related_more"
tools:visibility="visible" />
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/container_bottom_sheet"