Like the old grid but using a card view + play button Increased memory size of glide + remove cross fade being on by defaultpull/3117/head
parent
489ef7a5f8
commit
a07de130a9
@ -0,0 +1,63 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.catalogue.browse
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
|
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||||
|
import com.bumptech.glide.signature.ObjectKey
|
||||||
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaImpl
|
||||||
|
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||||
|
import eu.kanade.tachiyomi.ui.library.LibraryCategoryAdapter
|
||||||
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
|
import eu.kanade.tachiyomi.widget.StateImageViewTarget
|
||||||
|
import kotlinx.android.synthetic.main.catalogue_mat_grid_item.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to hold the displayed data of a manga in the library, like the cover or the title.
|
||||||
|
* All the elements from the layout file "item_catalogue_grid" are available in this class.
|
||||||
|
*
|
||||||
|
* @param view the inflated view for this holder.
|
||||||
|
* @param adapter the adapter handling this holder.
|
||||||
|
* @param listener a listener to react to single tap and long tap events.
|
||||||
|
* @constructor creates a new library holder.
|
||||||
|
*/
|
||||||
|
class CatalogueMatGridHolder(
|
||||||
|
private val view: View,
|
||||||
|
private val adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>) :
|
||||||
|
CatalogueHolder(view, adapter) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this
|
||||||
|
* holder with the given manga.
|
||||||
|
*
|
||||||
|
* @param manga the manga item to bind.
|
||||||
|
*/
|
||||||
|
override fun onSetValues(manga: Manga) {
|
||||||
|
// Update the title of the manga.
|
||||||
|
title.text = manga.currentTitle()
|
||||||
|
subtitle.gone()
|
||||||
|
|
||||||
|
bookmark_text.visibility = if (manga.favorite) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
|
// Update the cover.
|
||||||
|
setImage(manga)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setImage(manga: Manga) {
|
||||||
|
if (manga.thumbnail_url == null)
|
||||||
|
Glide.with(view.context).clear(cover_thumbnail)
|
||||||
|
else {
|
||||||
|
GlideApp.with(view.context)
|
||||||
|
.load(manga)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.DATA)
|
||||||
|
.centerCrop()
|
||||||
|
.placeholder(android.R.color.transparent)
|
||||||
|
.transition(DrawableTransitionOptions.withCrossFade())
|
||||||
|
.into(StateImageViewTarget(cover_thumbnail, progress))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.library
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
|
import com.bumptech.glide.signature.ObjectKey
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaImpl
|
||||||
|
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||||
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
|
import kotlinx.android.synthetic.main.catalogue_mat_grid_item.*
|
||||||
|
import kotlinx.android.synthetic.main.catalogue_mat_grid_item.view.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to hold the displayed data of a manga in the library, like the cover or the title.
|
||||||
|
* All the elements from the layout file "item_catalogue_grid" are available in this class.
|
||||||
|
*
|
||||||
|
* @param view the inflated view for this holder.
|
||||||
|
* @param adapter the adapter handling this holder.
|
||||||
|
* @param listener a listener to react to single tap and long tap events.
|
||||||
|
* @constructor creates a new library holder.
|
||||||
|
*/
|
||||||
|
class LibraryMatGridHolder(
|
||||||
|
private val view: View,
|
||||||
|
adapter: LibraryCategoryAdapter,
|
||||||
|
var width:Int,
|
||||||
|
var rowCount: Int
|
||||||
|
) : LibraryHolder(view, adapter) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this
|
||||||
|
* holder with the given manga.
|
||||||
|
*
|
||||||
|
* @param item the manga item to bind.
|
||||||
|
*/
|
||||||
|
override fun onSetValues(item: LibraryItem) {
|
||||||
|
// Update the title of the manga.
|
||||||
|
title.text = item.manga.currentTitle()
|
||||||
|
|
||||||
|
// Update the unread count and its visibility.
|
||||||
|
val unread = item.manga.unread
|
||||||
|
|
||||||
|
// Update the subtitle of the manga with artist or the unread count
|
||||||
|
with(subtitle) {
|
||||||
|
text = when {
|
||||||
|
item.manga.unread > 0 -> when (item.unreadType) {
|
||||||
|
1 -> view.resources.getQuantityString(R.plurals.unread_count, unread, unread)
|
||||||
|
0 -> view.resources.getString(R.string.new_chapter)
|
||||||
|
else -> item.manga.originalAuthor()
|
||||||
|
}
|
||||||
|
else -> item.manga.originalAuthor()
|
||||||
|
}
|
||||||
|
setTextColor(
|
||||||
|
view.context.getResourceColor(
|
||||||
|
if (item.manga.unread > 0 && item.unreadType > -1) android.R.attr.colorAccent
|
||||||
|
else android.R.attr.textColorSecondary
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
play_button.visibility = if (unread > 0) View.VISIBLE else View.GONE
|
||||||
|
play_button.setOnClickListener { playButtonClicked() }
|
||||||
|
|
||||||
|
// Update the download count and its visibility.
|
||||||
|
with(download_text) {
|
||||||
|
visibility = if (item.downloadCount > 0) View.VISIBLE else View.GONE
|
||||||
|
text = item.downloadCount.toString()
|
||||||
|
}
|
||||||
|
// Set local visibility if its local manga
|
||||||
|
local_text.visibility = if (item.manga.source == LocalSource.ID) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
|
// Update the cover.
|
||||||
|
if (item.manga.thumbnail_url == null) Glide.with(view.context).clear(cover_thumbnail)
|
||||||
|
else {
|
||||||
|
val id = item.manga.id ?: return
|
||||||
|
GlideApp.with(view.context).load(item.manga)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
|
||||||
|
.signature(ObjectKey(MangaImpl.getLastCoverFetch(id).toString()))
|
||||||
|
.into(cover_thumbnail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun playButtonClicked() {
|
||||||
|
adapter.libraryListener.startReading(adapterPosition)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActionStateChanged(position: Int, actionState: Int) {
|
||||||
|
super.onActionStateChanged(position, actionState)
|
||||||
|
if (actionState == 2) {
|
||||||
|
view.card.isDragged = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemReleased(position: Int) {
|
||||||
|
super.onItemReleased(position)
|
||||||
|
view.card.isDragged = false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:color="@color/selectorColor">
|
||||||
|
<item android:id="@android:id/mask"
|
||||||
|
android:top="0dp"
|
||||||
|
android:bottom="12dp"
|
||||||
|
android:left="4dp"
|
||||||
|
android:right="4dp">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<corners android:radius="4dp" />
|
||||||
|
<solid android:color="@color/selectorColor" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
android:top="0dp"
|
||||||
|
android:bottom="12dp"
|
||||||
|
android:left="4dp"
|
||||||
|
android:right="4dp">
|
||||||
|
<selector>
|
||||||
|
<item android:state_selected="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<corners android:radius="4dp" />
|
||||||
|
<solid android:color="@color/selectorColor" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:state_activated="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<corners android:radius="4dp" />
|
||||||
|
<solid android:color="@color/selectorColor" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
|
</item>
|
||||||
|
</ripple>
|
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
tools:background="#FFFF00"
|
||||||
|
android:color="?android:attr/colorAccent">
|
||||||
|
<item android:id="@android:id/mask">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="?android:attr/colorAccent" />
|
||||||
|
<corners android:radius="13dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:id="@android:id/background">
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="16dp"/>
|
||||||
|
<size
|
||||||
|
android:height="32dp"
|
||||||
|
android:width="32dp" />
|
||||||
|
<solid android:color="#AD212121"/>
|
||||||
|
<stroke android:width="0.1dp" android:color="#EDEDED" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</ripple>
|
@ -0,0 +1,187 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/manga_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/constraint_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="@drawable/library_item_selector"
|
||||||
|
android:minHeight="200dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/card"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginStart="6dp"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/title"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="1.0">
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/cover_thumbnail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:background="?android:attr/colorBackground"
|
||||||
|
android:maxHeight="250dp"
|
||||||
|
app:layout_constrainedHeight="true"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:background="?android:attr/colorBackground"
|
||||||
|
tools:ignore="ContentDescription"
|
||||||
|
tools:src="@mipmap/ic_launcher" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/badge_layout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginTop="4dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/local_text"
|
||||||
|
style="@style/TextAppearance.Regular.Caption.Light"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/md_teal_500"
|
||||||
|
android:paddingStart="3dp"
|
||||||
|
android:paddingTop="1dp"
|
||||||
|
android:paddingEnd="3dp"
|
||||||
|
android:paddingBottom="1dp"
|
||||||
|
android:text="@string/local_source_badge"
|
||||||
|
android:textColor="@color/md_white_1000"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/download_text"
|
||||||
|
style="@style/TextAppearance.Regular.Caption.Light"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="-10dp"
|
||||||
|
android:layout_marginTop="-10dp"
|
||||||
|
android:background="@drawable/dialog_rounded_background"
|
||||||
|
android:backgroundTint="@color/md_red_500"
|
||||||
|
android:gravity="start|center"
|
||||||
|
android:paddingStart="14dp"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:paddingBottom="3dp"
|
||||||
|
android:textColor="@color/md_white_1000"
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/local_text"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="1" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/bookmark_text"
|
||||||
|
style="@style/TextAppearance.Regular.Caption.Light"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="-10dp"
|
||||||
|
android:layout_marginTop="-10dp"
|
||||||
|
android:background="@drawable/dialog_rounded_background"
|
||||||
|
android:backgroundTint="@color/md_blue_A400_87"
|
||||||
|
android:gravity="start|center"
|
||||||
|
android:paddingStart="14dp"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:paddingBottom="3dp"
|
||||||
|
android:textColor="@color/md_white_1000"
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/local_text"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:text="@string/in_library"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/play_button"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_gravity="end|bottom"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
|
android:layout_marginBottom="6dp"
|
||||||
|
android:background="@drawable/round_play_background"
|
||||||
|
android:contentDescription="@string/start_reading"
|
||||||
|
android:src="@drawable/ic_play_arrow_white_24dp"
|
||||||
|
android:tint="@android:color/white"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress"
|
||||||
|
style="?android:attr/progressBarStyleSmall"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
style="@style/TextAppearance.Regular.Body1.Light"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="6dp"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:lineSpacingExtra="-4dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/subtitle"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:text="Sample name\nsdf" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/subtitle"
|
||||||
|
style="@style/TextAppearance.Regular.Body1.Light"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="14dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:lineSpacingExtra="-4dp"
|
||||||
|
android:paddingStart="6dp"
|
||||||
|
android:paddingEnd="6dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:text="Sample artist" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</FrameLayout>
|
Loading…
Reference in new issue