mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Grid items optimizations (#6641)
Use ConstraintLayout for ez size ratio calculation and merge cover-only view holder with compact's
This commit is contained in:
		| @@ -1,6 +1,5 @@ | ||||
| package eu.kanade.tachiyomi.ui.browse.source.browse | ||||
|  | ||||
| import android.view.View | ||||
| import androidx.core.view.isVisible | ||||
| import coil.clear | ||||
| import coil.imageLoader | ||||
| @@ -16,14 +15,14 @@ import eu.kanade.tachiyomi.widget.StateImageViewTarget | ||||
|  * Class used to hold the displayed data of a manga in the catalogue, like the cover or the title. | ||||
|  * All the elements from the layout file "item_source_grid" are available in this class. | ||||
|  * | ||||
|  * @param view the inflated view for this holder. | ||||
|  * @param binding the inflated view for this holder. | ||||
|  * @param adapter the adapter handling this holder. | ||||
|  * @constructor creates a new catalogue holder. | ||||
|  */ | ||||
| class SourceComfortableGridHolder(private val view: View, private val adapter: FlexibleAdapter<*>) : | ||||
|     SourceHolder<SourceComfortableGridItemBinding>(view, adapter) { | ||||
|  | ||||
|     override val binding = SourceComfortableGridItemBinding.bind(view) | ||||
| class SourceComfortableGridHolder( | ||||
|     override val binding: SourceComfortableGridItemBinding, | ||||
|     adapter: FlexibleAdapter<*> | ||||
| ) : SourceHolder<SourceComfortableGridItemBinding>(binding.root, adapter) { | ||||
|  | ||||
|     /** | ||||
|      * Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this | ||||
| @@ -49,15 +48,12 @@ class SourceComfortableGridHolder(private val view: View, private val adapter: F | ||||
|     } | ||||
|  | ||||
|     override fun setImage(manga: Manga) { | ||||
|         // For rounded corners | ||||
|         binding.card.clipToOutline = true | ||||
|  | ||||
|         binding.thumbnail.clear() | ||||
|         if (!manga.thumbnail_url.isNullOrEmpty()) { | ||||
|             val crossfadeDuration = view.context.imageLoader.defaults.transition.let { | ||||
|             val crossfadeDuration = binding.root.context.imageLoader.defaults.transition.let { | ||||
|                 if (it is CrossfadeTransition) it.durationMillis else 0 | ||||
|             } | ||||
|             val request = ImageRequest.Builder(view.context) | ||||
|             val request = ImageRequest.Builder(binding.root.context) | ||||
|                 .data(manga) | ||||
|                 .setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false) | ||||
|                 .target(StateImageViewTarget(binding.thumbnail, binding.progress, crossfadeDuration)) | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| package eu.kanade.tachiyomi.ui.browse.source.browse | ||||
|  | ||||
| import android.view.View | ||||
| import androidx.core.view.isVisible | ||||
| import coil.clear | ||||
| import coil.imageLoader | ||||
| @@ -16,14 +15,14 @@ import eu.kanade.tachiyomi.widget.StateImageViewTarget | ||||
|  * Class used to hold the displayed data of a manga in the catalogue, like the cover or the title. | ||||
|  * All the elements from the layout file "item_source_grid" are available in this class. | ||||
|  * | ||||
|  * @param view the inflated view for this holder. | ||||
|  * @param binding the inflated view for this holder. | ||||
|  * @param adapter the adapter handling this holder. | ||||
|  * @constructor creates a new catalogue holder. | ||||
|  */ | ||||
| open class SourceCompactGridHolder(private val view: View, private val adapter: FlexibleAdapter<*>) : | ||||
|     SourceHolder<SourceCompactGridItemBinding>(view, adapter) { | ||||
|  | ||||
|     override val binding = SourceCompactGridItemBinding.bind(view) | ||||
| class SourceCompactGridHolder( | ||||
|     override val binding: SourceCompactGridItemBinding, | ||||
|     adapter: FlexibleAdapter<*> | ||||
| ) : SourceHolder<SourceCompactGridItemBinding>(binding.root, adapter) { | ||||
|  | ||||
|     /** | ||||
|      * Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this | ||||
| @@ -49,15 +48,12 @@ open class SourceCompactGridHolder(private val view: View, private val adapter: | ||||
|     } | ||||
|  | ||||
|     override fun setImage(manga: Manga) { | ||||
|         // For rounded corners | ||||
|         binding.card.clipToOutline = true | ||||
|  | ||||
|         binding.thumbnail.clear() | ||||
|         if (!manga.thumbnail_url.isNullOrEmpty()) { | ||||
|             val crossfadeDuration = view.context.imageLoader.defaults.transition.let { | ||||
|             val crossfadeDuration = binding.root.context.imageLoader.defaults.transition.let { | ||||
|                 if (it is CrossfadeTransition) it.durationMillis else 0 | ||||
|             } | ||||
|             val request = ImageRequest.Builder(view.context) | ||||
|             val request = ImageRequest.Builder(binding.root.context) | ||||
|                 .data(manga) | ||||
|                 .setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false) | ||||
|                 .target(StateImageViewTarget(binding.thumbnail, binding.progress, crossfadeDuration)) | ||||
|   | ||||
| @@ -1,10 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.ui.browse.source.browse | ||||
|  | ||||
| import android.view.Gravity | ||||
| import android.view.View | ||||
| import android.view.ViewGroup.LayoutParams.MATCH_PARENT | ||||
| import android.widget.FrameLayout | ||||
| import androidx.constraintlayout.widget.ConstraintLayout | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import com.fredporciuncula.flow.preferences.Preference | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| @@ -15,16 +11,15 @@ import eu.kanade.tachiyomi.data.database.models.Manga | ||||
| import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding | ||||
| import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding | ||||
| import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting | ||||
| import eu.kanade.tachiyomi.widget.AutofitRecyclerView | ||||
|  | ||||
| class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayModeSetting>) : | ||||
|     AbstractFlexibleItem<SourceHolder<*>>() { | ||||
|  | ||||
|     override fun getLayoutRes(): Int { | ||||
|         return when (displayMode.get()) { | ||||
|             DisplayModeSetting.LIST -> R.layout.source_list_item | ||||
|             DisplayModeSetting.COMPACT_GRID, DisplayModeSetting.COVER_ONLY_GRID -> R.layout.source_compact_grid_item | ||||
|             DisplayModeSetting.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item | ||||
|             else -> R.layout.source_compact_grid_item | ||||
|             DisplayModeSetting.LIST -> R.layout.source_list_item | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -33,37 +28,14 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo | ||||
|         adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>> | ||||
|     ): SourceHolder<*> { | ||||
|         return when (displayMode.get()) { | ||||
|             DisplayModeSetting.LIST -> { | ||||
|                 SourceListHolder(view, adapter) | ||||
|             DisplayModeSetting.COMPACT_GRID, DisplayModeSetting.COVER_ONLY_GRID -> { | ||||
|                 SourceCompactGridHolder(SourceCompactGridItemBinding.bind(view), adapter) | ||||
|             } | ||||
|             DisplayModeSetting.COMFORTABLE_GRID -> { | ||||
|                 val binding = SourceComfortableGridItemBinding.bind(view) | ||||
|                 val parent = adapter.recyclerView as AutofitRecyclerView | ||||
|                 val coverHeight = parent.itemWidth / 3 * 4 | ||||
|                 view.apply { | ||||
|                     binding.card.layoutParams = ConstraintLayout.LayoutParams( | ||||
|                         MATCH_PARENT, | ||||
|                         coverHeight | ||||
|                     ) | ||||
|                 } | ||||
|                 SourceComfortableGridHolder(view, adapter) | ||||
|                 SourceComfortableGridHolder(SourceComfortableGridItemBinding.bind(view), adapter) | ||||
|             } | ||||
|             else -> { | ||||
|                 val binding = SourceCompactGridItemBinding.bind(view) | ||||
|                 val parent = adapter.recyclerView as AutofitRecyclerView | ||||
|                 val coverHeight = parent.itemWidth / 3 * 4 | ||||
|                 view.apply { | ||||
|                     binding.card.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, | ||||
|                         coverHeight | ||||
|                     ) | ||||
|                     binding.gradient.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, | ||||
|                         coverHeight / 2, | ||||
|                         Gravity.BOTTOM | ||||
|                     ) | ||||
|                 } | ||||
|                 SourceCompactGridHolder(view, adapter) | ||||
|             DisplayModeSetting.LIST -> { | ||||
|                 SourceListHolder(view, adapter) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| package eu.kanade.tachiyomi.ui.library | ||||
|  | ||||
| import android.view.View | ||||
| import androidx.core.view.isVisible | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import coil.clear | ||||
| @@ -13,17 +12,15 @@ import eu.kanade.tachiyomi.util.view.loadAnyAutoPause | ||||
|  * 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_source_grid" are available in this class. | ||||
|  * | ||||
|  * @param view the inflated view for this holder. | ||||
|  * @param binding 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 LibraryComfortableGridHolder( | ||||
|     private val view: View, | ||||
|     override val binding: SourceComfortableGridItemBinding, | ||||
|     adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>> | ||||
| ) : LibraryHolder<SourceComfortableGridItemBinding>(view, adapter) { | ||||
|  | ||||
|     override val binding = SourceComfortableGridItemBinding.bind(view) | ||||
| ) : LibraryHolder<SourceComfortableGridItemBinding>(binding.root, adapter) { | ||||
|  | ||||
|     /** | ||||
|      * Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this | ||||
| @@ -57,9 +54,6 @@ class LibraryComfortableGridHolder( | ||||
|         // set local visibility if its local manga | ||||
|         binding.badges.localText.isVisible = item.isLocal | ||||
|  | ||||
|         // For rounded corners | ||||
|         binding.card.clipToOutline = true | ||||
|  | ||||
|         // Update the cover. | ||||
|         binding.thumbnail.clear() | ||||
|         binding.thumbnail.loadAnyAutoPause(item.manga) | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| package eu.kanade.tachiyomi.ui.library | ||||
|  | ||||
| import android.view.View | ||||
| import androidx.core.view.isVisible | ||||
| import coil.clear | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| @@ -9,19 +8,18 @@ import eu.kanade.tachiyomi.util.view.loadAnyAutoPause | ||||
|  | ||||
| /** | ||||
|  * 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_source_grid" are available in this class. | ||||
|  * All the elements from the layout file "source_compact_grid_item" are available in this class. | ||||
|  * | ||||
|  * @param view the inflated view for this holder. | ||||
|  * @param binding 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. | ||||
|  * @param coverOnly true if title should be hidden a.k.a cover only mode. | ||||
|  * @constructor creates a new library holder. | ||||
|  */ | ||||
| open class LibraryCompactGridHolder( | ||||
|     private val view: View, | ||||
|     private val adapter: FlexibleAdapter<*> | ||||
| ) : LibraryHolder<SourceCompactGridItemBinding>(view, adapter) { | ||||
|  | ||||
|     override val binding = SourceCompactGridItemBinding.bind(view) | ||||
| class LibraryCompactGridHolder( | ||||
|     override val binding: SourceCompactGridItemBinding, | ||||
|     adapter: FlexibleAdapter<*>, | ||||
|     private val coverOnly: Boolean | ||||
| ) : LibraryHolder<SourceCompactGridItemBinding>(binding.root, adapter) { | ||||
|  | ||||
|     /** | ||||
|      * Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this | ||||
| @@ -55,11 +53,20 @@ open class LibraryCompactGridHolder( | ||||
|         // set local visibility if its local manga | ||||
|         binding.badges.localText.isVisible = item.isLocal | ||||
|  | ||||
|         // For rounded corners | ||||
|         binding.card.clipToOutline = true | ||||
|  | ||||
|         // Update the cover. | ||||
|         binding.thumbnail.clear() | ||||
|         binding.thumbnail.loadAnyAutoPause(item.manga) | ||||
|         if (coverOnly) { | ||||
|             // Cover only mode: Hides title text unless thumbnail is unavailable | ||||
|             if (!item.manga.thumbnail_url.isNullOrEmpty()) { | ||||
|                 binding.thumbnail.loadAnyAutoPause(item.manga) | ||||
|                 binding.title.isVisible = false | ||||
|             } else { | ||||
|                 binding.title.text = item.manga.title | ||||
|                 binding.title.isVisible = true | ||||
|             } | ||||
|             binding.thumbnail.foreground = null | ||||
|         } else { | ||||
|             binding.thumbnail.loadAnyAutoPause(item.manga) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,60 +0,0 @@ | ||||
| package eu.kanade.tachiyomi.ui.library | ||||
|  | ||||
| import android.view.View | ||||
| import androidx.core.view.isVisible | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import coil.clear | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.IFlexible | ||||
| import eu.kanade.tachiyomi.databinding.SourceCoverOnlyGridItemBinding | ||||
| import eu.kanade.tachiyomi.util.view.loadAnyAutoPause | ||||
|  | ||||
| class LibraryCoverOnlyGridHolder( | ||||
|     view: View, | ||||
|     adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>> | ||||
| ) : LibraryHolder<SourceCoverOnlyGridItemBinding>(view, adapter) { | ||||
|  | ||||
|     override val binding = SourceCoverOnlyGridItemBinding.bind(view) | ||||
|  | ||||
|     /** | ||||
|      * 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) { | ||||
|         // For rounded corners | ||||
|         binding.badges.leftBadges.clipToOutline = true | ||||
|         binding.badges.rightBadges.clipToOutline = true | ||||
|  | ||||
|         // Update the unread count and its visibility. | ||||
|         with(binding.badges.unreadText) { | ||||
|             isVisible = item.unreadCount > 0 | ||||
|             text = item.unreadCount.toString() | ||||
|         } | ||||
|         // Update the download count and its visibility. | ||||
|         with(binding.badges.downloadText) { | ||||
|             isVisible = item.downloadCount > 0 | ||||
|             text = item.downloadCount.toString() | ||||
|         } | ||||
|         // Update the source language and its visibility | ||||
|         with(binding.badges.languageText) { | ||||
|             isVisible = item.sourceLanguage.isNotEmpty() | ||||
|             text = item.sourceLanguage | ||||
|         } | ||||
|         // set local visibility if its local manga | ||||
|         binding.badges.localText.isVisible = item.isLocal | ||||
|  | ||||
|         // For rounded corners | ||||
|         binding.card.clipToOutline = true | ||||
|  | ||||
|         // Update the cover. | ||||
|         binding.thumbnail.clear() | ||||
|         if (!item.manga.thumbnail_url.isNullOrEmpty()) { | ||||
|             binding.thumbnail.loadAnyAutoPause(item.manga) | ||||
|         } else { | ||||
|             // Set manga title | ||||
|             binding.title.text = item.manga.title | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,10 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.ui.library | ||||
|  | ||||
| import android.view.Gravity | ||||
| import android.view.View | ||||
| import android.view.ViewGroup.LayoutParams.MATCH_PARENT | ||||
| import android.widget.FrameLayout | ||||
| import androidx.constraintlayout.widget.ConstraintLayout | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import com.fredporciuncula.flow.preferences.Preference | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| @@ -15,10 +11,8 @@ import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.database.models.LibraryManga | ||||
| import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding | ||||
| import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding | ||||
| import eu.kanade.tachiyomi.databinding.SourceCoverOnlyGridItemBinding | ||||
| import eu.kanade.tachiyomi.source.SourceManager | ||||
| import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting | ||||
| import eu.kanade.tachiyomi.widget.AutofitRecyclerView | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
|  | ||||
| @@ -47,9 +41,8 @@ class LibraryItem( | ||||
|  | ||||
|     override fun getLayoutRes(): Int { | ||||
|         return when (getDisplayMode()) { | ||||
|             DisplayModeSetting.COMPACT_GRID -> R.layout.source_compact_grid_item | ||||
|             DisplayModeSetting.COMPACT_GRID, DisplayModeSetting.COVER_ONLY_GRID -> R.layout.source_compact_grid_item | ||||
|             DisplayModeSetting.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item | ||||
|             DisplayModeSetting.COVER_ONLY_GRID -> R.layout.source_cover_only_grid_item | ||||
|             DisplayModeSetting.LIST -> R.layout.source_list_item | ||||
|         } | ||||
|     } | ||||
| @@ -57,42 +50,13 @@ class LibraryItem( | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder<*> { | ||||
|         return when (getDisplayMode()) { | ||||
|             DisplayModeSetting.COMPACT_GRID -> { | ||||
|                 val binding = SourceCompactGridItemBinding.bind(view) | ||||
|                 val parent = adapter.recyclerView as AutofitRecyclerView | ||||
|                 val coverHeight = parent.itemWidth / 3 * 4 | ||||
|                 view.apply { | ||||
|                     binding.card.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight) | ||||
|                     binding.gradient.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, | ||||
|                         coverHeight / 2, | ||||
|                         Gravity.BOTTOM | ||||
|                     ) | ||||
|                 } | ||||
|                 LibraryCompactGridHolder(view, adapter) | ||||
|             } | ||||
|             DisplayModeSetting.COMFORTABLE_GRID -> { | ||||
|                 val binding = SourceComfortableGridItemBinding.bind(view) | ||||
|                 val parent = adapter.recyclerView as AutofitRecyclerView | ||||
|                 val coverHeight = parent.itemWidth / 3 * 4 | ||||
|                 view.apply { | ||||
|                     binding.card.layoutParams = ConstraintLayout.LayoutParams( | ||||
|                         MATCH_PARENT, | ||||
|                         coverHeight | ||||
|                     ) | ||||
|                 } | ||||
|                 LibraryComfortableGridHolder(view, adapter) | ||||
|                 LibraryCompactGridHolder(SourceCompactGridItemBinding.bind(view), adapter, coverOnly = false) | ||||
|             } | ||||
|             DisplayModeSetting.COVER_ONLY_GRID -> { | ||||
|                 val binding = SourceCoverOnlyGridItemBinding.bind(view) | ||||
|                 val parent = adapter.recyclerView as AutofitRecyclerView | ||||
|                 val coverHeight = parent.itemWidth / 3 * 4 | ||||
|                 view.apply { | ||||
|                     binding.card.layoutParams = ConstraintLayout.LayoutParams( | ||||
|                         MATCH_PARENT, | ||||
|                         coverHeight | ||||
|                     ) | ||||
|                 } | ||||
|                 LibraryCoverOnlyGridHolder(view, adapter) | ||||
|                 LibraryCompactGridHolder(SourceCompactGridItemBinding.bind(view), adapter, coverOnly = true) | ||||
|             } | ||||
|             DisplayModeSetting.COMFORTABLE_GRID -> { | ||||
|                 LibraryComfortableGridHolder(SourceComfortableGridItemBinding.bind(view), adapter) | ||||
|             } | ||||
|             DisplayModeSetting.LIST -> { | ||||
|                 LibraryListHolder(view, adapter) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user