Fix badge alignment on details screen

This commit is contained in:
Koitharu
2022-10-01 13:06:00 +03:00
parent 893fa6bd90
commit e00ed13ad1
4 changed files with 77 additions and 10 deletions

View File

@@ -60,6 +60,7 @@ android {
'-opt-in=kotlinx.coroutines.FlowPreview',
'-opt-in=kotlin.contracts.ExperimentalContracts',
'-opt-in=coil.annotation.ExperimentalCoilApi',
'-opt-in=com.google.android.material.badge.ExperimentalBadgeUtils',
]
}
lint {

View File

@@ -19,12 +19,10 @@ import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.lifecycle.lifecycleScope
import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import kotlinx.coroutines.launch
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.domain.MangaIntent
@@ -37,12 +35,17 @@ import org.koitharu.kotatsu.core.ui.MangaErrorDialog
import org.koitharu.kotatsu.databinding.ActivityDetailsBinding
import org.koitharu.kotatsu.details.ui.model.HistoryInfo
import org.koitharu.kotatsu.download.ui.service.DownloadService
import org.koitharu.kotatsu.list.ui.adapter.bindBadge
import org.koitharu.kotatsu.main.ui.owners.NoModalBottomSheetOwner
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.reader.ui.ReaderActivity
import org.koitharu.kotatsu.reader.ui.ReaderState
import org.koitharu.kotatsu.utils.ext.*
import org.koitharu.kotatsu.utils.ViewBadge
import org.koitharu.kotatsu.utils.ext.assistedViewModels
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
import org.koitharu.kotatsu.utils.ext.isReportable
import org.koitharu.kotatsu.utils.ext.setNavigationBarTransparentCompat
import org.koitharu.kotatsu.utils.ext.textAndVisible
import javax.inject.Inject
@AndroidEntryPoint
class DetailsActivity :
@@ -60,7 +63,7 @@ class DetailsActivity :
@Inject
lateinit var shortcutsUpdater: ShortcutsUpdater
private var badge: BadgeDrawable? = null
private lateinit var viewBadge: ViewBadge
private val viewModel: DetailsViewModel by assistedViewModels {
viewModelFactory.create(MangaIntent(intent))
@@ -83,6 +86,7 @@ class DetailsActivity :
}
binding.buttonRead.setOnClickListener(this)
binding.buttonDropdown.setOnClickListener(this)
viewBadge = ViewBadge(binding.buttonRead, this)
chaptersMenuProvider = if (binding.layoutBottom != null) {
val bsMediator = ChaptersBottomSheetMediator(checkNotNull(binding.layoutBottom))
@@ -151,6 +155,7 @@ class DetailsActivity :
)
}
}
R.id.button_dropdown -> showBranchPopupMenu()
}
}
@@ -188,10 +193,12 @@ class DetailsActivity :
ExceptionResolver.canResolve(e) -> {
resolveError(e)
}
manga == null -> {
Toast.makeText(this, e.getDisplayMessage(resources), Toast.LENGTH_LONG).show()
finishAfterTransition()
}
else -> {
val snackbar = makeSnackbar(
e.getDisplayMessage(resources),
@@ -242,7 +249,7 @@ class DetailsActivity :
}
private fun onNewChaptersChanged(newChapters: Int) {
badge = binding.buttonRead.bindBadge(badge, newChapters)
viewBadge.counter = newChapters
}
fun showChapterMissingDialog(chapterId: Long) {

View File

@@ -1,8 +1,5 @@
@file:SuppressLint("UnsafeOptInUsageError")
package org.koitharu.kotatsu.list.ui.adapter
import android.annotation.SuppressLint
import android.view.View
import androidx.annotation.CheckResult
import androidx.core.view.doOnNextLayout
@@ -42,4 +39,4 @@ private fun initBadge(anchor: View): BadgeDrawable {
private fun BadgeDrawable.align() {
horizontalOffset = intrinsicWidth
verticalOffset = intrinsicHeight
}
}

View File

@@ -0,0 +1,62 @@
package org.koitharu.kotatsu.utils
import android.view.View
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.badge.BadgeUtils
class ViewBadge(
private val anchor: View,
lifecycleOwner: LifecycleOwner,
) : View.OnLayoutChangeListener, DefaultLifecycleObserver {
private var badgeDrawable: BadgeDrawable? = null
var counter: Int
get() = badgeDrawable?.number ?: 0
set(value) {
val badge = badgeDrawable ?: initBadge()
badge.number = value
badge.isVisible = value > 0
}
init {
lifecycleOwner.lifecycle.addObserver(this)
}
override fun onLayoutChange(
v: View?,
left: Int,
top: Int,
right: Int,
bottom: Int,
oldLeft: Int,
oldTop: Int,
oldRight: Int,
oldBottom: Int,
) {
val badge = badgeDrawable ?: return
BadgeUtils.setBadgeDrawableBounds(badge, anchor, null)
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
clearBadge()
}
private fun initBadge(): BadgeDrawable {
val badge = BadgeDrawable.create(anchor.context)
anchor.addOnLayoutChangeListener(this)
BadgeUtils.attachBadgeDrawable(badge, anchor)
badgeDrawable = badge
return badge
}
private fun clearBadge() {
val badge = badgeDrawable ?: return
anchor.removeOnLayoutChangeListener(this)
BadgeUtils.detachBadgeDrawable(badge, anchor)
badgeDrawable = null
}
}