More binding for library (and some reader) views

This commit is contained in:
Jays2Kings 2021-03-29 01:50:10 -04:00
parent e5405ac381
commit 028ed3ea1e
18 changed files with 284 additions and 277 deletions

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.UnreadDownloadBadgeBinding
import eu.kanade.tachiyomi.util.system.contextCompatColor import eu.kanade.tachiyomi.util.system.contextCompatColor
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.gone
@ -11,11 +12,17 @@ import eu.kanade.tachiyomi.util.view.isVisible
import eu.kanade.tachiyomi.util.view.setTextColorRes import eu.kanade.tachiyomi.util.view.setTextColorRes
import eu.kanade.tachiyomi.util.view.updatePaddingRelative import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import eu.kanade.tachiyomi.util.view.visibleIf import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.unread_download_badge.view.*
class LibraryBadge @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class LibraryBadge @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
MaterialCardView(context, attrs) { MaterialCardView(context, attrs) {
private lateinit var binding: UnreadDownloadBadgeBinding
override fun onFinishInflate() {
super.onFinishInflate()
binding = UnreadDownloadBadgeBinding.bind(this)
}
fun setUnreadDownload(unread: Int, downloads: Int, showTotalChapters: Boolean) { fun setUnreadDownload(unread: Int, downloads: Int, showTotalChapters: Boolean) {
// Update the unread count and its visibility. // Update the unread count and its visibility.
@ -23,7 +30,7 @@ class LibraryBadge @JvmOverloads constructor(context: Context, attrs: AttributeS
if (showTotalChapters) R.color.total_badge else R.color.unread_badge if (showTotalChapters) R.color.total_badge else R.color.unread_badge
) )
with(unread_text) { with(binding.unreadText) {
visibleIf(unread > 0 || unread == -1 || showTotalChapters) visibleIf(unread > 0 || unread == -1 || showTotalChapters)
if (!isVisible()) { if (!isVisible()) {
return@with return@with
@ -41,7 +48,7 @@ class LibraryBadge @JvmOverloads constructor(context: Context, attrs: AttributeS
} }
// Update the download count or local status and its visibility. // Update the download count or local status and its visibility.
with(download_text) { with(binding.downloadText) {
visibleIf(downloads == -2 || downloads > 0) visibleIf(downloads == -2 || downloads > 0)
if (!isVisible()) { return@with } if (!isVisible()) { return@with }
text = if (downloads == -2) { text = if (downloads == -2) {
@ -52,18 +59,18 @@ class LibraryBadge @JvmOverloads constructor(context: Context, attrs: AttributeS
} }
// Show the badge card if unread or downloads exists // Show the badge card if unread or downloads exists
visibleIf(download_text.isVisible() || unread_text.isVisible()) visibleIf(binding.downloadText.isVisible() || binding.unreadText.isVisible())
// Show the angles divider if both unread and downloads exists // Show the angles divider if both unread and downloads exists
unread_angle.visibleIf(download_text.isVisible() && unread_text.isVisible()) binding.unreadAngle.visibleIf(binding.downloadText.isVisible() && binding.unreadText.isVisible())
unread_angle.setColorFilter(unreadBadgeBackground) binding.unreadAngle.setColorFilter(unreadBadgeBackground)
if (unread_angle.isVisible()) { if (binding.unreadAngle.isVisible()) {
download_text.updatePaddingRelative(end = 8.dpToPx) binding.downloadText.updatePaddingRelative(end = 8.dpToPx)
unread_text.updatePaddingRelative(start = 2.dpToPx) binding.unreadText.updatePaddingRelative(start = 2.dpToPx)
} else { } else {
download_text.updatePaddingRelative(end = 5.dpToPx) binding.downloadText.updatePaddingRelative(end = 5.dpToPx)
unread_text.updatePaddingRelative(start = 5.dpToPx) binding.unreadText.updatePaddingRelative(start = 5.dpToPx)
} }
} }
@ -73,9 +80,9 @@ class LibraryBadge @JvmOverloads constructor(context: Context, attrs: AttributeS
fun setInLibrary(inLibrary: Boolean) { fun setInLibrary(inLibrary: Boolean) {
this.visibleIf(inLibrary) this.visibleIf(inLibrary)
unread_angle.gone() binding.unreadAngle.gone()
unread_text.updatePaddingRelative(start = 5.dpToPx) binding.unreadText.updatePaddingRelative(start = 5.dpToPx)
unread_text.visibleIf(inLibrary) binding.unreadText.visibleIf(inLibrary)
unread_text.text = resources.getText(R.string.in_library) binding.unreadText.text = resources.getText(R.string.in_library)
} }
} }

View File

@ -9,10 +9,9 @@ import coil.size.Precision
import coil.size.Scale import coil.size.Scale
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.image.coil.loadLibraryManga import eu.kanade.tachiyomi.data.image.coil.loadLibraryManga
import eu.kanade.tachiyomi.databinding.MangaGridItemBinding
import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.visibleIf import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.manga_grid_item.*
import kotlinx.android.synthetic.main.unread_download_badge.*
/** /**
* Class used to hold the displayed data of a manga in the library, like the cover or the title. * Class used to hold the displayed data of a manga in the library, like the cover or the title.
@ -31,19 +30,20 @@ class LibraryGridHolder(
private var fixedSize: Boolean private var fixedSize: Boolean
) : LibraryHolder(view, adapter) { ) : LibraryHolder(view, adapter) {
private val binding = MangaGridItemBinding.bind(view)
init { init {
play_layout.setOnClickListener { playButtonClicked() } binding.playLayout.setOnClickListener { playButtonClicked() }
if (compact) { if (compact) {
text_layout.gone() binding.textLayout.gone()
} else { } else {
compact_title.gone() binding.compactTitle.gone()
gradient.gone() binding.gradient.gone()
val playLayout = play_layout.layoutParams as FrameLayout.LayoutParams val playLayout = binding.playLayout.layoutParams as FrameLayout.LayoutParams
val buttonLayout = play_button.layoutParams as FrameLayout.LayoutParams val buttonLayout = binding.playButton.layoutParams as FrameLayout.LayoutParams
playLayout.gravity = Gravity.BOTTOM or Gravity.END playLayout.gravity = Gravity.BOTTOM or Gravity.END
buttonLayout.gravity = Gravity.BOTTOM or Gravity.END buttonLayout.gravity = Gravity.BOTTOM or Gravity.END
play_layout.layoutParams = playLayout binding.playLayout.layoutParams = playLayout
play_button.layoutParams = buttonLayout binding.playButton.layoutParams = buttonLayout
} }
} }
@ -55,19 +55,19 @@ class LibraryGridHolder(
*/ */
override fun onSetValues(item: LibraryItem) { override fun onSetValues(item: LibraryItem) {
// Update the title and subtitle of the manga. // Update the title and subtitle of the manga.
constraint_layout.visibleIf(!item.manga.isBlank()) binding.constraintLayout.visibleIf(!item.manga.isBlank())
title.text = item.manga.title binding.title.text = item.manga.title
subtitle.text = item.manga.author?.trim() binding.subtitle.text = item.manga.author?.trim()
compact_title.text = title.text binding.compactTitle.text = binding.title.text
setUnreadBadge(badge_view, item) setUnreadBadge(binding.unreadDownloadBadge.badgeView, item)
setReadingButton(item) setReadingButton(item)
// Update the cover. // Update the cover.
if (item.manga.thumbnail_url == null) cover_thumbnail.clear() if (item.manga.thumbnail_url == null) binding.coverThumbnail.clear()
else { else {
if (cover_thumbnail.height == 0) { if (binding.coverThumbnail.height == 0) {
val oldPos = flexibleAdapterPosition val oldPos = flexibleAdapterPosition
adapter.recyclerView.post { adapter.recyclerView.post {
if (oldPos == flexibleAdapterPosition) { if (oldPos == flexibleAdapterPosition) {
@ -80,7 +80,7 @@ class LibraryGridHolder(
private fun setCover(manga: Manga) { private fun setCover(manga: Manga) {
if ((adapter.recyclerView.context as? Activity)?.isDestroyed == true) return if ((adapter.recyclerView.context as? Activity)?.isDestroyed == true) return
cover_thumbnail.loadLibraryManga(manga) { binding.coverThumbnail.loadLibraryManga(manga) {
if (!fixedSize) { if (!fixedSize) {
precision(Precision.INEXACT) precision(Precision.INEXACT)
scale(Scale.FIT) scale(Scale.FIT)
@ -95,14 +95,14 @@ class LibraryGridHolder(
override fun onActionStateChanged(position: Int, actionState: Int) { override fun onActionStateChanged(position: Int, actionState: Int) {
super.onActionStateChanged(position, actionState) super.onActionStateChanged(position, actionState)
if (actionState == 2) { if (actionState == 2) {
card.isDragged = true binding.card.isDragged = true
badge_view.isDragged = true binding.unreadDownloadBadge.badgeView.isDragged = true
} }
} }
override fun onItemReleased(position: Int) { override fun onItemReleased(position: Int) {
super.onItemReleased(position) super.onItemReleased(position)
card.isDragged = false binding.card.isDragged = false
badge_view.isDragged = false binding.unreadDownloadBadge.badgeView.isDragged = false
} }
} }

View File

@ -4,9 +4,6 @@ import android.app.Activity
import android.graphics.Color import android.graphics.Color
import android.util.TypedValue import android.util.TypedValue
import android.view.View import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.github.florent37.viewtooltip.ViewTooltip import com.github.florent37.viewtooltip.ViewTooltip
@ -15,6 +12,7 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.LibraryCategoryHeaderItemBinding
import eu.kanade.tachiyomi.source.icon import eu.kanade.tachiyomi.source.icon
import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
@ -25,39 +23,32 @@ import eu.kanade.tachiyomi.util.view.invisible
import eu.kanade.tachiyomi.util.view.updateLayoutParams import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.visibleIf import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.library_category_header_item.*
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAdapter) : class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAdapter) :
BaseFlexibleViewHolder(view, adapter, true) { BaseFlexibleViewHolder(view, adapter, true) {
private val sectionText: TextView = view.findViewById(R.id.category_title) private val binding = LibraryCategoryHeaderItemBinding.bind(view)
private val sortText: TextView = view.findViewById(R.id.category_sort)
private val updateButton: ImageView = view.findViewById(R.id.update_button)
private val checkboxImage: ImageView = view.findViewById(R.id.checkbox)
private val expandImage: ImageView = view.findViewById(R.id.collapse_arrow)
private val catProgress: ProgressBar = view.findViewById(R.id.cat_progress)
init { init {
category_header_layout.setOnClickListener { toggleCategory() } binding.categoryHeaderLayout.setOnClickListener { toggleCategory() }
updateButton.setOnClickListener { addCategoryToUpdate() } binding.updateButton.setOnClickListener { addCategoryToUpdate() }
sectionText.setOnLongClickListener { binding.categoryTitle.setOnLongClickListener {
val category = (adapter.getItem(flexibleAdapterPosition) as? LibraryHeaderItem)?.category val category = (adapter.getItem(flexibleAdapterPosition) as? LibraryHeaderItem)?.category
adapter.libraryListener.manageCategory(flexibleAdapterPosition) adapter.libraryListener.manageCategory(flexibleAdapterPosition)
category?.isDynamic == false category?.isDynamic == false
} }
sectionText.setOnClickListener { toggleCategory() } binding.categoryTitle.setOnClickListener { toggleCategory() }
sortText.setOnClickListener { it.post { showCatSortOptions() } } binding.categorySort.setOnClickListener { it.post { showCatSortOptions() } }
checkboxImage.setOnClickListener { selectAll() } binding.checkbox.setOnClickListener { selectAll() }
updateButton.drawable.mutate() binding.updateButton.drawable.mutate()
} }
private fun toggleCategory() { private fun toggleCategory() {
adapter.libraryListener.toggleCategoryVisibility(flexibleAdapterPosition) adapter.libraryListener.toggleCategoryVisibility(flexibleAdapterPosition)
val tutorial = Injekt.get<PreferencesHelper>().shownLongPressCategoryTutorial() val tutorial = Injekt.get<PreferencesHelper>().shownLongPressCategoryTutorial()
if (!tutorial.get()) { if (!tutorial.get()) {
ViewTooltip.on(itemView.context as? Activity, sectionText).autoHide(true, 5000L) ViewTooltip.on(itemView.context as? Activity, binding.categoryTitle).autoHide(true, 5000L)
.align(ViewTooltip.ALIGN.START).position(ViewTooltip.Position.TOP) .align(ViewTooltip.ALIGN.START).position(ViewTooltip.Position.TOP)
.text(R.string.long_press_category) .text(R.string.long_press_category)
.color(itemView.context.getResourceColor(R.attr.colorAccent)) .color(itemView.context.getResourceColor(R.attr.colorAccent))
@ -78,7 +69,7 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
false false
} }
val shorterMargin = adapter.headerItems.firstOrNull() == item val shorterMargin = adapter.headerItems.firstOrNull() == item
sectionText.updateLayoutParams<ConstraintLayout.LayoutParams> { binding.categoryTitle.updateLayoutParams<ConstraintLayout.LayoutParams> {
topMargin = ( topMargin = (
when { when {
shorterMargin -> 2 shorterMargin -> 2
@ -90,21 +81,21 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
val category = item.category val category = item.category
if (category.isDynamic) { if (category.isDynamic) {
category_header_layout.background = null binding.categoryHeaderLayout.background = null
sectionText.background = null binding.categoryTitle.background = null
} else { } else {
category_header_layout.setBackgroundResource(R.drawable.list_item_selector) binding.categoryHeaderLayout.setBackgroundResource(R.drawable.list_item_selector)
sectionText.setBackgroundResource(R.drawable.square_ripple) binding.categoryTitle.setBackgroundResource(R.drawable.square_ripple)
} }
if (category.isAlone && !category.isDynamic) sectionText.text = "" if (category.isAlone && !category.isDynamic) binding.categoryTitle.text = ""
else sectionText.text = category.name else binding.categoryTitle.text = category.name
if (category.sourceId != null) { if (category.sourceId != null) {
val icon = adapter.sourceManager.get(category.sourceId!!)?.icon() val icon = adapter.sourceManager.get(category.sourceId!!)?.icon()
icon?.setBounds(0, 0, 32.dpToPx, 32.dpToPx) icon?.setBounds(0, 0, 32.dpToPx, 32.dpToPx)
sectionText.setCompoundDrawablesRelative(icon, null, null, null) binding.categoryTitle.setCompoundDrawablesRelative(icon, null, null, null)
} else { } else {
sectionText.setCompoundDrawablesRelative(null, null, null, null) binding.categoryTitle.setCompoundDrawablesRelative(null, null, null, null)
} }
val isAscending = category.isAscending() val isAscending = category.isAscending()
@ -115,45 +106,45 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
else -> R.drawable.ic_arrow_upward_24dp else -> R.drawable.ic_arrow_upward_24dp
} }
sortText.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, sortDrawable, 0) binding.categorySort.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, sortDrawable, 0)
sortText.setText(category.sortRes()) binding.categorySort.setText(category.sortRes())
expandImage.setImageResource( binding.collapseArrow.setImageResource(
if (category.isHidden) R.drawable.ic_expand_more_24dp if (category.isHidden) R.drawable.ic_expand_more_24dp
else R.drawable.ic_expand_less_24dp else R.drawable.ic_expand_less_24dp
) )
when { when {
adapter.mode == SelectableAdapter.Mode.MULTI -> { adapter.mode == SelectableAdapter.Mode.MULTI -> {
checkboxImage.visibleIf(!category.isHidden) binding.checkbox.visibleIf(!category.isHidden)
expandImage.visibleIf(category.isHidden && !adapter.isSingleCategory && !category.isDynamic) binding.collapseArrow.visibleIf(category.isHidden && !adapter.isSingleCategory && !category.isDynamic)
updateButton.gone() binding.updateButton.gone()
catProgress.gone() binding.catProgress.gone()
setSelection() setSelection()
} }
category.id ?: -1 < 0 -> { category.id ?: -1 < 0 -> {
expandImage.gone() binding.collapseArrow.gone()
checkboxImage.gone() binding.checkbox.gone()
catProgress.gone() binding.catProgress.gone()
updateButton.gone() binding.updateButton.gone()
} }
LibraryUpdateService.categoryInQueue(category.id) -> { LibraryUpdateService.categoryInQueue(category.id) -> {
expandImage.visibleIf(!adapter.isSingleCategory && !category.isDynamic) binding.collapseArrow.visibleIf(!adapter.isSingleCategory && !category.isDynamic)
checkboxImage.gone() binding.checkbox.gone()
catProgress.visible() binding.catProgress.visible()
updateButton.invisible() binding.updateButton.invisible()
} }
else -> { else -> {
expandImage.visibleIf(!adapter.isSingleCategory && !category.isDynamic) binding.collapseArrow.visibleIf(!adapter.isSingleCategory && !category.isDynamic)
catProgress.gone() binding.catProgress.gone()
checkboxImage.gone() binding.checkbox.gone()
updateButton.visibleIf(!adapter.isSingleCategory) binding.updateButton.visibleIf(!adapter.isSingleCategory)
} }
} }
} }
private fun addCategoryToUpdate() { private fun addCategoryToUpdate() {
if (adapter.libraryListener.updateCategory(flexibleAdapterPosition)) { if (adapter.libraryListener.updateCategory(flexibleAdapterPosition)) {
catProgress.visible() binding.catProgress.visible()
updateButton.invisible() binding.updateButton.invisible()
} }
} }
@ -278,7 +269,7 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
else R.color.gray_button else R.color.gray_button
) )
) )
checkboxImage.setImageDrawable(tintedDrawable) binding.checkbox.setImageDrawable(tintedDrawable)
} }
override fun onLongClick(view: View?): Boolean { override fun onLongClick(view: View?): Boolean {

View File

@ -5,22 +5,19 @@ import android.view.ViewGroup
import coil.api.clear import coil.api.clear
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.image.coil.loadLibraryManga import eu.kanade.tachiyomi.data.image.coil.loadLibraryManga
import eu.kanade.tachiyomi.databinding.MangaListItemBinding
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.updateLayoutParams import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.visibleIf import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.manga_list_item.*
import kotlinx.android.synthetic.main.manga_list_item.view.*
import kotlinx.android.synthetic.main.unread_download_badge.*
/** /**
* Class used to hold the displayed data of a manga in the library, like the cover or the title. * Class used to hold the displayed data of a manga in the library, like the cover or the binding.title.
* All the elements from the layout file "item_library_list" are available in this class. * All the elements from the layout file "item_library_list" are available in this class.
* *
* @param view the inflated view for this holder. * @param view the inflated view for this holder.
* @param adapter the adapter handling 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. * @constructor creates a new library holder.
*/ */
@ -29,6 +26,8 @@ class LibraryListHolder(
adapter: LibraryCategoryAdapter adapter: LibraryCategoryAdapter
) : LibraryHolder(view, adapter) { ) : LibraryHolder(view, adapter) {
private val binding = MangaListItemBinding.bind(view)
/** /**
* Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this * Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this
* holder with the given manga. * holder with the given manga.
@ -36,62 +35,62 @@ class LibraryListHolder(
* @param item the manga item to bind. * @param item the manga item to bind.
*/ */
override fun onSetValues(item: LibraryItem) { override fun onSetValues(item: LibraryItem) {
title.visible() binding.title.visible()
constraint_layout.minHeight = 56.dpToPx binding.constraintLayout.minHeight = 56.dpToPx
if (item.manga.isBlank()) { if (item.manga.isBlank()) {
constraint_layout.minHeight = 0 binding.constraintLayout.minHeight = 0
constraint_layout.updateLayoutParams<ViewGroup.MarginLayoutParams> { binding.constraintLayout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height = ViewGroup.MarginLayoutParams.WRAP_CONTENT height = ViewGroup.MarginLayoutParams.WRAP_CONTENT
} }
if (item.manga.status == -1) { if (item.manga.status == -1) {
title.text = null binding.title.text = null
title.gone() binding.title.gone()
} else { } else {
title.text = itemView.context.getString(R.string.category_is_empty) binding.title.text = itemView.context.getString(R.string.category_is_empty)
} }
title.textAlignment = View.TEXT_ALIGNMENT_CENTER binding.title.textAlignment = View.TEXT_ALIGNMENT_CENTER
card.gone() binding.card.gone()
badge_view.gone() binding.unreadDownloadBadge.badgeView.gone()
padding.gone() binding.padding.gone()
subtitle.gone() binding.subtitle.gone()
return return
} }
constraint_layout.updateLayoutParams<ViewGroup.MarginLayoutParams> { binding.constraintLayout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height = 52.dpToPx height = 52.dpToPx
} }
padding.visible() binding.padding.visible()
card.visible() binding.card.visible()
title.textAlignment = View.TEXT_ALIGNMENT_TEXT_START binding.title.textAlignment = View.TEXT_ALIGNMENT_TEXT_START
// Update the title of the manga. // Update the binding.title of the manga.
title.text = item.manga.title binding.title.text = item.manga.title
setUnreadBadge(badge_view, item) setUnreadBadge(binding.unreadDownloadBadge.badgeView, item)
subtitle.text = item.manga.author?.trim() binding.subtitle.text = item.manga.author?.trim()
title.post { binding.title.post {
if (title?.text == item.manga.title) { if (binding.title.text == item.manga.title) {
subtitle.visibleIf(title.lineCount == 1 && !item.manga.author.isNullOrBlank()) binding.subtitle.visibleIf(binding.title.lineCount == 1 && !item.manga.author.isNullOrBlank())
} }
} }
// Update the cover. // Update the cover.
if (item.manga.thumbnail_url == null) { if (item.manga.thumbnail_url == null) {
cover_thumbnail.clear() binding.coverThumbnail.clear()
} else { } else {
val id = item.manga.id ?: return item.manga.id ?: return
cover_thumbnail.loadLibraryManga(item.manga) binding.coverThumbnail.loadLibraryManga(item.manga)
} }
} }
override fun onActionStateChanged(position: Int, actionState: Int) { override fun onActionStateChanged(position: Int, actionState: Int) {
super.onActionStateChanged(position, actionState) super.onActionStateChanged(position, actionState)
if (actionState == 2) { if (actionState == 2) {
view.card.isDragged = true binding.card.isDragged = true
} }
} }
override fun onItemReleased(position: Int) { override fun onItemReleased(position: Int) {
super.onItemReleased(position) super.onItemReleased(position)
view.card.isDragged = false binding.card.isDragged = false
} }
} }

View File

@ -2,21 +2,23 @@ package eu.kanade.tachiyomi.ui.library.display
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import eu.kanade.tachiyomi.databinding.LibraryBadgesLayoutBinding
import eu.kanade.tachiyomi.util.bindToPreference import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView
import kotlinx.android.synthetic.main.library_badges_layout.view.* import kotlinx.android.synthetic.main.library_badges_layout.view.*
class LibraryBadgesView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class LibraryBadgesView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseLibraryDisplayView(context, attrs) { BaseLibraryDisplayView<LibraryBadgesLayoutBinding>(context, attrs) {
override fun inflateBinding() = LibraryBadgesLayoutBinding.bind(this)
override fun initGeneralPreferences() { override fun initGeneralPreferences() {
unread_badge_group.bindToPreference(preferences.unreadBadgeType()) { binding.unreadBadgeGroup.bindToPreference(preferences.unreadBadgeType()) {
controller.presenter.requestUnreadBadgesUpdate() controller.presenter.requestUnreadBadgesUpdate()
} }
hide_reading.bindToPreference(preferences.hideStartReadingButton()) { binding.hideReading.bindToPreference(preferences.hideStartReadingButton()) {
controller.reattachAdapter() controller.reattachAdapter()
} }
download_badge.bindToPreference(preferences.downloadBadge()) { binding.downloadBadge.bindToPreference(preferences.downloadBadge()) {
controller.presenter.requestDownloadBadgesUpdate() controller.presenter.requestDownloadBadgesUpdate()
} }
} }

View File

@ -2,29 +2,30 @@ package eu.kanade.tachiyomi.ui.library.display
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import eu.kanade.tachiyomi.databinding.LibraryCategoryLayoutBinding
import eu.kanade.tachiyomi.util.bindToPreference import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView
import kotlinx.android.synthetic.main.library_category_layout.view.*
class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseLibraryDisplayView(context, attrs) { BaseLibraryDisplayView<LibraryCategoryLayoutBinding>(context, attrs) {
override fun inflateBinding() = LibraryCategoryLayoutBinding.bind(this)
override fun initGeneralPreferences() { override fun initGeneralPreferences() {
show_all.bindToPreference(preferences.showAllCategories()) { binding.showAll.bindToPreference(preferences.showAllCategories()) {
controller.presenter.getLibrary() controller.presenter.getLibrary()
category_show.isEnabled = it binding.categoryShow.isEnabled = it
} }
category_show.isEnabled = show_all.isChecked binding.categoryShow.isEnabled = binding.showAll.isChecked
category_show.bindToPreference(preferences.showCategoryInTitle()) { binding.categoryShow.bindToPreference(preferences.showCategoryInTitle()) {
controller.showMiniBar() controller.showMiniBar()
} }
hide_hopper.bindToPreference(preferences.hideHopper()) { binding.hideHopper.bindToPreference(preferences.hideHopper()) {
controller.hideHopper(it) controller.hideHopper(it)
} }
auto_hide_hopper.bindToPreference(preferences.autohideHopper()) { binding.autoHideHopper.bindToPreference(preferences.autohideHopper()) {
controller.resetHopperY() controller.resetHopperY()
} }
add_categories_button.setOnClickListener { binding.addCategoriesButton.setOnClickListener {
controller.showCategoriesController() controller.showCategoriesController()
} }
} }

View File

@ -2,21 +2,22 @@ package eu.kanade.tachiyomi.ui.library.display
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import eu.kanade.tachiyomi.databinding.LibraryDisplayLayoutBinding
import eu.kanade.tachiyomi.util.bindToPreference import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView
import kotlinx.android.synthetic.main.library_display_layout.view.*
class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseLibraryDisplayView(context, attrs) { BaseLibraryDisplayView<LibraryDisplayLayoutBinding>(context, attrs) {
override fun inflateBinding() = LibraryDisplayLayoutBinding.bind(this)
override fun initGeneralPreferences() { override fun initGeneralPreferences() {
display_group.bindToPreference(preferences.libraryLayout()) { binding.displayGroup.bindToPreference(preferences.libraryLayout()) {
controller.reattachAdapter() controller.reattachAdapter()
} }
uniform_grid.bindToPreference(preferences.uniformGrid()) { binding.uniformGrid.bindToPreference(preferences.uniformGrid()) {
controller.reattachAdapter() controller.reattachAdapter()
} }
grid_size_toggle_group.bindToPreference(preferences.gridSize()) { binding.gridSizeToggleGroup.bindToPreference(preferences.gridSize()) {
controller.reattachAdapter() controller.reattachAdapter()
} }
} }

View File

@ -9,7 +9,6 @@ import eu.kanade.tachiyomi.ui.setting.SettingsLibraryController
import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.withFadeTransaction import eu.kanade.tachiyomi.util.view.withFadeTransaction
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
open class TabbedLibraryDisplaySheet(val controller: LibraryController) : open class TabbedLibraryDisplaySheet(val controller: LibraryController) :
TabbedBottomSheetDialog(controller.activity!!) { TabbedBottomSheetDialog(controller.activity!!) {
@ -22,17 +21,17 @@ open class TabbedLibraryDisplaySheet(val controller: LibraryController) :
displayView.controller = controller displayView.controller = controller
badgesView.controller = controller badgesView.controller = controller
categoryView.controller = controller categoryView.controller = controller
menu.visible() binding.menu.visible()
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
menu.tooltipText = context.getString(R.string.more_library_settings) binding.menu.tooltipText = context.getString(R.string.more_library_settings)
} }
menu.setImageDrawable( binding.menu.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.ic_settings_24dp R.drawable.ic_settings_24dp
) )
) )
menu.setOnClickListener { binding.menu.setOnClickListener {
controller.router.pushController(SettingsLibraryController().withFadeTransaction()) controller.router.pushController(SettingsLibraryController().withFadeTransaction())
dismiss() dismiss()
} }

View File

@ -18,11 +18,12 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.databinding.FilterBottomSheetBinding
import eu.kanade.tachiyomi.ui.library.LibraryController import eu.kanade.tachiyomi.ui.library.LibraryController
import eu.kanade.tachiyomi.ui.library.LibraryGroup import eu.kanade.tachiyomi.ui.library.LibraryGroup
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.launchUI import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.view.activityBinding
import eu.kanade.tachiyomi.util.view.collapse import eu.kanade.tachiyomi.util.view.collapse
import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.hide import eu.kanade.tachiyomi.util.view.hide
@ -31,12 +32,6 @@ import eu.kanade.tachiyomi.util.view.isExpanded
import eu.kanade.tachiyomi.util.view.isHidden import eu.kanade.tachiyomi.util.view.isHidden
import eu.kanade.tachiyomi.util.view.updatePaddingRelative import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import eu.kanade.tachiyomi.util.view.visibleIf import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.filter_bottom_sheet.view.*
import kotlinx.android.synthetic.main.library_grid_recycler.*
import kotlinx.android.synthetic.main.library_list_controller.*
import kotlinx.android.synthetic.main.main_activity.*
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
import kotlinx.android.synthetic.main.track_item.*
import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
@ -58,6 +53,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
*/ */
private val preferences: PreferencesHelper by injectLazy() private val preferences: PreferencesHelper by injectLazy()
private lateinit var binding: FilterBottomSheetBinding
private val trackManager: TrackManager by injectLazy() private val trackManager: TrackManager by injectLazy()
private val hasTracking private val hasTracking
@ -100,23 +97,28 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
var controller: LibraryController? = null var controller: LibraryController? = null
var bottomBarHeight = 0 var bottomBarHeight = 0
override fun onFinishInflate() {
super.onFinishInflate()
binding = FilterBottomSheetBinding.bind(this)
}
fun onCreate(controller: LibraryController) { fun onCreate(controller: LibraryController) {
clearButton = clear_button clearButton = binding.clearButton
filter_layout.removeView(clearButton) binding.filterLayout.removeView(clearButton)
sheetBehavior = BottomSheetBehavior.from(this) sheetBehavior = BottomSheetBehavior.from(this)
sheetBehavior?.isHideable = true sheetBehavior?.isHideable = true
this.controller = controller this.controller = controller
libraryRecyler = controller.recycler libraryRecyler = controller.binding.libraryGridRecycler.recycler
libraryRecyler?.post { libraryRecyler?.post {
bottomBarHeight = (this@FilterBottomSheet.controller?.activity as? MainActivity)?.bottom_nav?.height ?: 0 bottomBarHeight = controller.activityBinding?.bottomNav?.height ?: 0
} }
val shadow2: View = controller.shadow2 val shadow2: View = controller.binding.shadow2
val shadow: View = controller.shadow val shadow: View = controller.binding.shadow
sheetBehavior?.addBottomSheetCallback( sheetBehavior?.addBottomSheetCallback(
object : BottomSheetBehavior.BottomSheetCallback() { object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, progress: Float) { override fun onSlide(bottomSheet: View, progress: Float) {
this@FilterBottomSheet.controller?.updateFilterSheetY() this@FilterBottomSheet.controller?.updateFilterSheetY()
pill.alpha = (1 - max(0f, progress)) * 0.25f binding.pill.alpha = (1 - max(0f, progress)) * 0.25f
shadow2.alpha = (1 - max(0f, progress)) * 0.25f shadow2.alpha = (1 - max(0f, progress)) * 0.25f
shadow.alpha = 1 + min(0f, progress) shadow.alpha = 1 + min(0f, progress)
updateRootPadding(progress) updateRootPadding(progress)
@ -130,29 +132,26 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
) )
post { post {
second_layout ?: return@post if (binding.secondLayout.width + binding.firstLayout.width + 20.dpToPx < width) {
first_layout ?: return@post binding.secondLayout.removeView(binding.viewOptions)
view_options ?: return@post binding.secondLayout.removeView(binding.reorderFilters)
if (second_layout.width + first_layout.width + 20.dpToPx < width) { binding.firstLayout.addView(binding.reorderFilters)
second_layout.removeView(view_options) binding.firstLayout.addView(binding.viewOptions)
second_layout.removeView(reorder_filters) binding.secondLayout.gone()
first_layout.addView(reorder_filters)
first_layout.addView(view_options)
second_layout.gone()
} }
} }
sheetBehavior?.hide() sheetBehavior?.hide()
expand_categories.setOnClickListener { binding.expandCategories.setOnClickListener {
onGroupClicked(ACTION_EXPAND_COLLAPSE_ALL) onGroupClicked(ACTION_EXPAND_COLLAPSE_ALL)
} }
group_by.setOnClickListener { binding.groupBy.setOnClickListener {
onGroupClicked(ACTION_GROUP_BY) onGroupClicked(ACTION_GROUP_BY)
} }
view_options.setOnClickListener { binding.viewOptions.setOnClickListener {
onGroupClicked(ACTION_DISPLAY) onGroupClicked(ACTION_DISPLAY)
} }
reorder_filters.setOnClickListener { binding.reorderFilters.setOnClickListener {
manageFilterPopup() manageFilterPopup()
} }
@ -178,14 +177,14 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
} }
fun setExpandText(expand: Boolean) { fun setExpandText(expand: Boolean) {
expand_categories.setText( binding.expandCategories.setText(
if (expand) { if (expand) {
R.string.expand_all_categories R.string.expand_all_categories
} else { } else {
R.string.collapse_all_categories R.string.collapse_all_categories
} }
) )
expand_categories.setIconResource( binding.expandCategories.setIconResource(
if (expand) { if (expand) {
R.drawable.ic_expand_less_24dp R.drawable.ic_expand_less_24dp
} else { } else {
@ -195,14 +194,14 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
} }
private fun stateChanged(state: Int) { private fun stateChanged(state: Int) {
val shadow = controller?.shadow ?: return val shadow = controller?.binding?.shadow ?: return
controller?.updateHopperY() controller?.updateHopperY()
if (state == BottomSheetBehavior.STATE_COLLAPSED) { if (state == BottomSheetBehavior.STATE_COLLAPSED) {
shadow.alpha = 1f shadow.alpha = 1f
libraryRecyler?.updatePaddingRelative(bottom = sheetBehavior?.peekHeight ?: 0 + 10.dpToPx + bottomBarHeight) libraryRecyler?.updatePaddingRelative(bottom = sheetBehavior?.peekHeight ?: 0 + 10.dpToPx + bottomBarHeight)
} }
if (state == BottomSheetBehavior.STATE_EXPANDED) { if (state == BottomSheetBehavior.STATE_EXPANDED) {
pill.alpha = 0f binding.pill.alpha = 0f
} }
if (state == BottomSheetBehavior.STATE_HIDDEN) { if (state == BottomSheetBehavior.STATE_HIDDEN) {
onGroupClicked(ACTION_HIDE_FILTER_TIP) onGroupClicked(ACTION_HIDE_FILTER_TIP)
@ -328,7 +327,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
serviceNames.getOrNull(2) serviceNames.getOrNull(2)
) )
if (tracked?.isActivated == true) { if (tracked?.isActivated == true) {
filter_layout.addView(trackers) binding.filterLayout.addView(trackers)
filterItems.add(trackers!!) filterItems.add(trackers!!)
trackers?.setState(FILTER_TRACKER) trackers?.setState(FILTER_TRACKER)
reSortViews() reSortViews()
@ -457,15 +456,15 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
} }
val hasFilters = hasActiveFilters() val hasFilters = hasActiveFilters()
if (hasFilters && clearButton.parent == null) { if (hasFilters && clearButton.parent == null) {
filter_layout.addView(clearButton, 0) binding.filterLayout.addView(clearButton, 0)
} else if (!hasFilters && clearButton.parent != null) { } else if (!hasFilters && clearButton.parent != null) {
filter_layout.removeView(clearButton) binding.filterLayout.removeView(clearButton)
} }
if (tracked?.isActivated == true && trackers != null && trackers?.parent == null) { if (tracked?.isActivated == true && trackers != null && trackers?.parent == null) {
filter_layout.addView(trackers, filterItems.indexOf(tracked!!) + 2) binding.filterLayout.addView(trackers, filterItems.indexOf(tracked!!) + 2)
filterItems.add(filterItems.indexOf(tracked!!) + 1, trackers!!) filterItems.add(filterItems.indexOf(tracked!!) + 1, trackers!!)
} else if (tracked?.isActivated == false && trackers?.parent != null) { } else if (tracked?.isActivated == false && trackers?.parent != null) {
filter_layout.removeView(trackers) binding.filterLayout.removeView(trackers)
trackers?.reset() trackers?.reset()
FILTER_TRACKER = "" FILTER_TRACKER = ""
filterItems.remove(trackers!!) filterItems.remove(trackers!!)
@ -473,8 +472,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
} }
fun updateButtons(showExpand: Boolean, groupType: Int) { fun updateButtons(showExpand: Boolean, groupType: Int) {
expand_categories.visibleIf(showExpand && groupType == 0) binding.expandCategories.visibleIf(showExpand && groupType == 0)
group_by.setIconResource(LibraryGroup.groupTypeDrawableRes(groupType)) binding.groupBy.setIconResource(LibraryGroup.groupTypeDrawableRes(groupType))
} }
private fun clearFilters() { private fun clearFilters() {
@ -487,7 +486,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
val transition = androidx.transition.AutoTransition() val transition = androidx.transition.AutoTransition()
transition.duration = 150 transition.duration = 150
androidx.transition.TransitionManager.beginDelayedTransition(filter_layout, transition) androidx.transition.TransitionManager.beginDelayedTransition(binding.filterLayout, transition)
reorderFilters() reorderFilters()
filterItems.forEach { filterItems.forEach {
it.reset() it.reset()
@ -500,17 +499,17 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
} }
private fun reSortViews() { private fun reSortViews() {
filter_layout.removeAllViews() binding.filterLayout.removeAllViews()
if (filterItems.any { it.isActivated }) { if (filterItems.any { it.isActivated }) {
filter_layout.addView(clearButton) binding.filterLayout.addView(clearButton)
} }
filterItems.filter { it.isActivated }.forEach { filterItems.filter { it.isActivated }.forEach {
filter_layout.addView(it) binding.filterLayout.addView(it)
} }
filterItems.filterNot { it.isActivated }.forEach { filterItems.filterNot { it.isActivated }.forEach {
filter_layout.addView(it) binding.filterLayout.addView(it)
} }
filter_scroll.scrollTo(0, 0) binding.filterScroll.scrollTo(0, 0)
} }
companion object { companion object {

View File

@ -6,9 +6,9 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.CategoriesItemBinding
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.gone
import kotlinx.android.synthetic.main.categories_item.*
/** /**
* Category item for a recycler view. * Category item for a recycler view.
@ -74,15 +74,16 @@ class ManageFilterItem(val char: Char) : AbstractFlexibleItem<ManageFilterItem.H
class Holder(val view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>) : class Holder(val view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>) :
BaseFlexibleViewHolder(view, adapter, true) { BaseFlexibleViewHolder(view, adapter, true) {
private val binding = CategoriesItemBinding.bind(view)
init { init {
image.gone() binding.image.gone()
edit_button.gone() binding.editButton.gone()
edit_text.isEnabled = false binding.editText.isEnabled = false
setDragHandleView(reorder) setDragHandleView(binding.reorder)
} }
fun bind(char: Char) { fun bind(char: Char) {
title.setText( binding.title.setText(
when (char) { when (char) {
'u' -> R.string.read_progress 'u' -> R.string.read_progress
'r' -> R.string.unread 'r' -> R.string.unread

View File

@ -4,21 +4,20 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.widget.SeekBar import android.widget.SeekBar
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import eu.kanade.tachiyomi.databinding.ReaderColorFilterBinding
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
import kotlinx.android.synthetic.main.reader_color_filter.*
import kotlinx.android.synthetic.main.reader_color_filter.view.*
import kotlinx.android.synthetic.main.reader_general_layout.view.*
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.sample import kotlinx.coroutines.flow.sample
class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseReaderSettingsView(context, attrs) { BaseReaderSettingsView<ReaderColorFilterBinding>(context, attrs) {
override fun inflateBinding() = ReaderColorFilterBinding.bind(this)
override fun initGeneralPreferences() { override fun initGeneralPreferences() {
activity = context as ReaderActivity activity = context as? ReaderActivity ?: return
preferences.colorFilter().asFlow() preferences.colorFilter().asFlow()
.onEach { setColorFilter(it) } .onEach { setColorFilter(it) }
.launchIn(activity.scope) .launchIn(activity.scope)
@ -38,33 +37,33 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
val argb = setValues(color) val argb = setValues(color)
// Set brightness value // Set brightness value
txt_brightness_seekbar_value.text = brightness.toString() binding.txtBrightnessSeekbarValue.text = brightness.toString()
brightness_seekbar.progress = brightness binding.brightnessSeekbar.progress = brightness
// Initialize seekBar progress // Initialize seekBar progress
seekbar_color_filter_alpha.progress = argb[0] binding.seekbarColorFilterAlpha.progress = argb[0]
seekbar_color_filter_red.progress = argb[1] binding.seekbarColorFilterRed.progress = argb[1]
seekbar_color_filter_green.progress = argb[2] binding.seekbarColorFilterGreen.progress = argb[2]
seekbar_color_filter_blue.progress = argb[3] binding.seekbarColorFilterBlue.progress = argb[3]
// Set listeners // Set listeners
switch_color_filter.isChecked = preferences.colorFilter().get() binding.switchColorFilter.isChecked = preferences.colorFilter().get()
switch_color_filter.setOnCheckedChangeListener { _, isChecked -> binding.switchColorFilter.setOnCheckedChangeListener { _, isChecked ->
preferences.colorFilter().set(isChecked) preferences.colorFilter().set(isChecked)
} }
custom_brightness.isChecked = preferences.customBrightness().get() binding.customBrightness.isChecked = preferences.customBrightness().get()
custom_brightness.setOnCheckedChangeListener { _, isChecked -> binding.customBrightness.setOnCheckedChangeListener { _, isChecked ->
preferences.customBrightness().set(isChecked) preferences.customBrightness().set(isChecked)
} }
color_filter_mode.bindToPreference(preferences.colorFilterMode()) binding.colorFilterMode.bindToPreference(preferences.colorFilterMode())
seekbar_color_filter_alpha.setOnSeekBarChangeListener( binding.seekbarColorFilterAlpha.setOnSeekBarChangeListener(
object : SimpleSeekBarListener() { object : SimpleSeekBarListener() {
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
seekbar_color_filter_red.isEnabled = value > 0 && seekbar_color_filter_alpha.isEnabled binding.seekbarColorFilterRed.isEnabled = value > 0 && binding.seekbarColorFilterAlpha.isEnabled
seekbar_color_filter_green.isEnabled = value > 0 && seekbar_color_filter_alpha.isEnabled binding.seekbarColorFilterGreen.isEnabled = value > 0 && binding.seekbarColorFilterAlpha.isEnabled
seekbar_color_filter_blue.isEnabled = value > 0 && seekbar_color_filter_alpha.isEnabled binding.seekbarColorFilterBlue.isEnabled = value > 0 && binding.seekbarColorFilterAlpha.isEnabled
if (fromUser) { if (fromUser) {
setColorValue(value, ALPHA_MASK, 24) setColorValue(value, ALPHA_MASK, 24)
} }
@ -72,7 +71,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
} }
) )
seekbar_color_filter_red.setOnSeekBarChangeListener( binding.seekbarColorFilterRed.setOnSeekBarChangeListener(
object : SimpleSeekBarListener() { object : SimpleSeekBarListener() {
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
if (fromUser) { if (fromUser) {
@ -82,7 +81,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
} }
) )
seekbar_color_filter_green.setOnSeekBarChangeListener( binding.seekbarColorFilterGreen.setOnSeekBarChangeListener(
object : SimpleSeekBarListener() { object : SimpleSeekBarListener() {
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
if (fromUser) { if (fromUser) {
@ -92,7 +91,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
} }
) )
seekbar_color_filter_blue.setOnSeekBarChangeListener( binding.seekbarColorFilterBlue.setOnSeekBarChangeListener(
object : SimpleSeekBarListener() { object : SimpleSeekBarListener() {
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
if (fromUser) { if (fromUser) {
@ -102,7 +101,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
} }
) )
brightness_seekbar.setOnSeekBarChangeListener( binding.brightnessSeekbar.setOnSeekBarChangeListener(
object : SimpleSeekBarListener() { object : SimpleSeekBarListener() {
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
if (fromUser) { if (fromUser) {
@ -118,10 +117,10 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
* @param enabled determines if seekBar gets enabled * @param enabled determines if seekBar gets enabled
*/ */
private fun setColorFilterSeekBar(enabled: Boolean) { private fun setColorFilterSeekBar(enabled: Boolean) {
seekbar_color_filter_red.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled binding.seekbarColorFilterRed.isEnabled = binding.seekbarColorFilterAlpha.progress > 0 && enabled
seekbar_color_filter_green.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled binding.seekbarColorFilterGreen.isEnabled = binding.seekbarColorFilterAlpha.progress > 0 && enabled
seekbar_color_filter_blue.isEnabled = seekbar_color_filter_alpha.progress > 0 && enabled binding.seekbarColorFilterBlue.isEnabled = binding.seekbarColorFilterAlpha.progress > 0 && enabled
seekbar_color_filter_alpha.isEnabled = enabled binding.seekbarColorFilterAlpha.isEnabled = enabled
} }
/** /**
@ -129,7 +128,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
* @param enabled value which determines if seekBar gets enabled * @param enabled value which determines if seekBar gets enabled
*/ */
private fun setCustomBrightnessSeekBar(enabled: Boolean) { private fun setCustomBrightnessSeekBar(enabled: Boolean) {
brightness_seekbar.isEnabled = enabled binding.brightnessSeekbar.isEnabled = enabled
} }
/** /**
@ -143,10 +142,10 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
val blue = getBlueFromColor(color) val blue = getBlueFromColor(color)
// Initialize values // Initialize values
txt_color_filter_alpha_value.text = alpha.toString() binding.txtColorFilterAlphaValue.text = alpha.toString()
txt_color_filter_red_value.text = red.toString() binding.txtColorFilterRedValue.text = red.toString()
txt_color_filter_green_value.text = green.toString() binding.txtColorFilterGreenValue.text = green.toString()
txt_color_filter_blue_value.text = blue.toString() binding.txtColorFilterBlueValue.text = blue.toString()
return arrayOf(alpha, red, green, blue) return arrayOf(alpha, red, green, blue)
} }
@ -176,7 +175,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
private fun setCustomBrightnessValue(value: Int, isDisabled: Boolean = false) { private fun setCustomBrightnessValue(value: Int, isDisabled: Boolean = false) {
// Set black overlay visibility. // Set black overlay visibility.
if (!isDisabled) { if (!isDisabled) {
txt_brightness_seekbar_value.text = value.toString() binding.txtBrightnessSeekbarValue.text = value.toString()
} }
} }

View File

@ -2,17 +2,18 @@ package eu.kanade.tachiyomi.ui.reader.settings
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import eu.kanade.tachiyomi.databinding.ReaderGeneralLayoutBinding
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.bindToPreference import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
import kotlinx.android.synthetic.main.reader_general_layout.view.*
class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseReaderSettingsView(context, attrs) { BaseReaderSettingsView<ReaderGeneralLayoutBinding>(context, attrs) {
lateinit var sheet: TabbedReaderSettingsSheet lateinit var sheet: TabbedReaderSettingsSheet
override fun inflateBinding() = ReaderGeneralLayoutBinding.bind(this)
override fun initGeneralPreferences() { override fun initGeneralPreferences() {
viewer_series.onItemSelectedListener = { position -> binding.viewerSeries.onItemSelectedListener = { position ->
activity.presenter.setMangaViewer(position) activity.presenter.setMangaViewer(position)
val mangaViewer = activity.presenter.getMangaViewer() val mangaViewer = activity.presenter.getMangaViewer()
@ -22,13 +23,13 @@ class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: Attri
initPagerPreferences() initPagerPreferences()
} }
} }
viewer_series.setSelection((context as? ReaderActivity)?.presenter?.manga?.viewer ?: 0) binding.viewerSeries.setSelection((context as? ReaderActivity)?.presenter?.manga?.viewer ?: 0)
rotation_mode.bindToPreference(preferences.rotation(), 1) binding.rotationMode.bindToPreference(preferences.rotation(), 1)
background_color.bindToPreference(preferences.readerTheme(), 0) binding.backgroundColor.bindToPreference(preferences.readerTheme(), 0)
show_page_number.bindToPreference(preferences.showPageNumber()) binding.showPageNumber.bindToPreference(preferences.showPageNumber())
fullscreen.bindToPreference(preferences.fullscreen()) binding.fullscreen.bindToPreference(preferences.fullscreen())
keepscreen.bindToPreference(preferences.keepScreenOn()) binding.keepscreen.bindToPreference(preferences.keepScreenOn())
always_show_chapter_transition.bindToPreference(preferences.alwaysShowChapterTransition()) binding.alwaysShowChapterTransition.bindToPreference(preferences.alwaysShowChapterTransition())
} }
/** /**

View File

@ -5,36 +5,37 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.ReaderPagedLayoutBinding
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.bindToPreference import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.util.view.visibleIf import eu.kanade.tachiyomi.util.view.visibleIf
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
import kotlinx.android.synthetic.main.reader_paged_layout.view.*
class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseReaderSettingsView(context, attrs) { BaseReaderSettingsView<ReaderPagedLayoutBinding>(context, attrs) {
override fun inflateBinding() = ReaderPagedLayoutBinding.bind(this)
override fun initGeneralPreferences() { override fun initGeneralPreferences() {
scale_type.bindToPreference(preferences.imageScaleType(), 1) { binding.scaleType.bindToPreference(preferences.imageScaleType(), 1) {
val mangaViewer = (context as? ReaderActivity)?.presenter?.getMangaViewer() ?: 0 val mangaViewer = (context as? ReaderActivity)?.presenter?.getMangaViewer() ?: 0
val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS
updatePagedGroup(!isWebtoonView) updatePagedGroup(!isWebtoonView)
} }
zoom_start.bindToPreference(preferences.zoomStart(), 1) binding.zoomStart.bindToPreference(preferences.zoomStart(), 1)
crop_borders.bindToPreference(preferences.cropBorders()) binding.cropBorders.bindToPreference(preferences.cropBorders())
page_transitions.bindToPreference(preferences.pageTransitions()) binding.pageTransitions.bindToPreference(preferences.pageTransitions())
pager_nav.bindToPreference(preferences.navigationModePager()) binding.pagerNav.bindToPreference(preferences.navigationModePager())
pager_invert.bindToPreference(preferences.pagerNavInverted()) binding.pagerInvert.bindToPreference(preferences.pagerNavInverted())
extend_past_cutout.bindToPreference(preferences.pagerCutoutBehavior()) binding.extendPastCutout.bindToPreference(preferences.pagerCutoutBehavior())
val mangaViewer = (context as? ReaderActivity)?.presenter?.getMangaViewer() ?: 0 val mangaViewer = (context as? ReaderActivity)?.presenter?.getMangaViewer() ?: 0
val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS
val hasMargins = mangaViewer == ReaderActivity.VERTICAL_PLUS val hasMargins = mangaViewer == ReaderActivity.VERTICAL_PLUS
crop_borders_webtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon()) binding.cropBordersWebtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon())
webtoon_side_padding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values) binding.webtoonSidePadding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values)
webtoon_enable_zoom_out.bindToPreference(preferences.webtoonEnableZoomOut()) binding.webtoonEnableZoomOut.bindToPreference(preferences.webtoonEnableZoomOut())
webtoon_nav.bindToPreference(preferences.navigationModeWebtoon()) binding.webtoonNav.bindToPreference(preferences.navigationModeWebtoon())
webtoon_invert.bindToPreference(preferences.webtoonNavInverted()) binding.webtoonInvert.bindToPreference(preferences.webtoonNavInverted())
updatePagedGroup(!isWebtoonView) updatePagedGroup(!isWebtoonView)
} }
@ -43,13 +44,13 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
val mangaViewer = activity.presenter.getMangaViewer() val mangaViewer = activity.presenter.getMangaViewer()
val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS
val hasMargins = mangaViewer == ReaderActivity.VERTICAL_PLUS val hasMargins = mangaViewer == ReaderActivity.VERTICAL_PLUS
crop_borders_webtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon()) binding.cropBordersWebtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon())
updatePagedGroup(!isWebtoonView) updatePagedGroup(!isWebtoonView)
} }
private fun updatePagedGroup(show: Boolean) { private fun updatePagedGroup(show: Boolean) {
listOf(scale_type, zoom_start, crop_borders, page_transitions, pager_nav, pager_invert).forEach { it.visibleIf(show) } listOf(binding.scaleType, binding.zoomStart, binding.cropBorders, binding.pageTransitions, binding.pagerNav, binding.pagerInvert).forEach { it.visibleIf(show) }
listOf(crop_borders_webtoon, webtoon_side_padding, webtoon_enable_zoom_out, webtoon_nav, webtoon_invert).forEach { it.visibleIf(!show) } listOf(binding.cropBordersWebtoon, binding.webtoonSidePadding, binding.webtoonEnableZoomOut, binding.webtoonNav, binding.webtoonInvert).forEach { it.visibleIf(!show) }
val isFullFit = when (preferences.imageScaleType().get()) { val isFullFit = when (preferences.imageScaleType().get()) {
SubsamplingScaleImageView.SCALE_TYPE_FIT_HEIGHT, SubsamplingScaleImageView.SCALE_TYPE_FIT_HEIGHT,
SubsamplingScaleImageView.SCALE_TYPE_SMART_FIT, SubsamplingScaleImageView.SCALE_TYPE_SMART_FIT,
@ -62,6 +63,6 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
} else { } else {
false false
} }
extend_past_cutout.visibleIf(show && isFullFit && hasCutout) binding.extendPastCutout.visibleIf(show && isFullFit && hasCutout)
} }
} }

View File

@ -3,35 +3,39 @@ package eu.kanade.tachiyomi.widget
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import androidx.core.widget.NestedScrollView import androidx.core.widget.NestedScrollView
import androidx.viewbinding.ViewBinding
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.library.LibraryController import eu.kanade.tachiyomi.ui.library.LibraryController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
abstract class BaseTabbedScrollView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : abstract class BaseTabbedScrollView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
NestedScrollView(context, attrs) { NestedScrollView(context, attrs) {
protected lateinit var binding: VB
init { init {
clipToPadding = false clipToPadding = false
} }
internal val preferences by injectLazy<PreferencesHelper>() internal val preferences by injectLazy<PreferencesHelper>()
abstract fun initGeneralPreferences() abstract fun initGeneralPreferences()
abstract fun inflateBinding(): VB
override fun onFinishInflate() { override fun onFinishInflate() {
super.onFinishInflate() super.onFinishInflate()
binding = inflateBinding()
setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener) setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
initGeneralPreferences() initGeneralPreferences()
} }
} }
abstract class BaseLibraryDisplayView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : abstract class BaseLibraryDisplayView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseTabbedScrollView(context, attrs) { BaseTabbedScrollView<VB>(context, attrs) {
lateinit var controller: LibraryController lateinit var controller: LibraryController
} }
abstract class BaseReaderSettingsView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : abstract class BaseReaderSettingsView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseTabbedScrollView(context, attrs) { BaseTabbedScrollView<VB>(context, attrs) {
lateinit var activity: ReaderActivity lateinit var activity: ReaderActivity
} }

View File

@ -11,10 +11,10 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.TabbedBottomSheetBinding
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.expand import eu.kanade.tachiyomi.util.view.expand
import eu.kanade.tachiyomi.util.view.setEdgeToEdge import eu.kanade.tachiyomi.util.view.setEdgeToEdge
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
import kotlin.math.max import kotlin.math.max
abstract class TabbedBottomSheetDialog(private val activity: Activity) : abstract class TabbedBottomSheetDialog(private val activity: Activity) :
@ -22,30 +22,29 @@ abstract class TabbedBottomSheetDialog(private val activity: Activity) :
(activity, R.style.BottomSheetDialogTheme) { (activity, R.style.BottomSheetDialogTheme) {
private var sheetBehavior: BottomSheetBehavior<*> private var sheetBehavior: BottomSheetBehavior<*>
protected val binding = TabbedBottomSheetBinding.inflate(activity.layoutInflater)
open var offset = -1 open var offset = -1
init { init {
// Use activity theme for this layout // Use activity theme for this layout
val view = activity.layoutInflater.inflate(R.layout.tabbed_bottom_sheet, null) setContentView(binding.root)
sheetBehavior = BottomSheetBehavior.from(binding.root.parent as ViewGroup)
setContentView(view) setEdgeToEdge(activity, binding.root)
sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup)
setEdgeToEdge(activity, view)
val height = activity.window.decorView.rootWindowInsets.systemWindowInsetTop val height = activity.window.decorView.rootWindowInsets.systemWindowInsetTop
pager.maxHeight = activity.window.decorView.height - height - 125.dpToPx binding.pager.maxHeight = activity.window.decorView.height - height - 125.dpToPx
val adapter = TabbedSheetAdapter() val adapter = TabbedSheetAdapter()
pager.offscreenPageLimit = 2 binding.pager.offscreenPageLimit = 2
pager.adapter = adapter binding.pager.adapter = adapter
tabs.setupWithViewPager(pager) binding.tabs.setupWithViewPager(binding.pager)
} }
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
sheetBehavior.skipCollapsed = true sheetBehavior.skipCollapsed = true
sheetBehavior.expand() sheetBehavior.expand()
tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { binding.tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) { override fun onTabSelected(tab: TabLayout.Tab?) {
val view = getTabViews()[tab?.position ?: 0] as? NestedScrollView val view = getTabViews()[tab?.position ?: 0] as? NestedScrollView
view?.isNestedScrollingEnabled = true view?.isNestedScrollingEnabled = true
@ -95,8 +94,8 @@ class MeasuredViewPager @JvmOverloads constructor(context: Context, attrs: Attri
} }
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var heightMeasureSpec = heightMeasureSpec var heightSpec = heightMeasureSpec
super.onMeasure(widthMeasureSpec, heightMeasureSpec) super.onMeasure(widthMeasureSpec, heightSpec)
var height = 0 var height = 0
val childWidthSpec = MeasureSpec.makeMeasureSpec( val childWidthSpec = MeasureSpec.makeMeasureSpec(
max( max(
@ -113,11 +112,11 @@ class MeasuredViewPager @JvmOverloads constructor(context: Context, attrs: Attri
if (h > height) height = h if (h > height) height = h
} }
if (height != 0) { if (height != 0) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
} }
if (maxHeight < height + (rootWindowInsets?.systemWindowInsetBottom ?: 0)) { if (maxHeight < height + (rootWindowInsets?.systemWindowInsetBottom ?: 0)) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST) heightSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST)
} }
super.onMeasure(widthMeasureSpec, heightMeasureSpec) super.onMeasure(widthMeasureSpec, heightSpec)
} }
} }

View File

@ -61,7 +61,7 @@
android:contentDescription="@string/start_reading" android:contentDescription="@string/start_reading"
android:padding="6dp" android:padding="6dp"
android:src="@drawable/ic_start_reading_24dp" android:src="@drawable/ic_start_reading_24dp"
android:tint="@android:color/white" /> app:tint="@android:color/white" />
</FrameLayout> </FrameLayout>
@ -110,6 +110,7 @@
<include <include
layout="@layout/unread_download_badge" layout="@layout/unread_download_badge"
android:id="@+id/unread_download_badge"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_marginStart="1dp" android:layout_marginStart="1dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -91,6 +91,7 @@
tools:text="Manga artist" /> tools:text="Manga artist" />
<include layout="@layout/unread_download_badge" <include layout="@layout/unread_download_badge"
android:id="@+id/unread_download_badge"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="2dp" android:layout_marginStart="2dp"

View File

@ -20,6 +20,7 @@
android:id="@+id/spinner_end" android:id="@+id/spinner_end"
android:layout_width="16dp" android:layout_width="16dp"
android:layout_height="0dp" android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="parent" /> app:layout_constraintStart_toEndOf="parent" />
<!-- Color filter --> <!-- Color filter -->