Adding blur to overflow dialog + manga cover blur on tap

This commit is contained in:
Jays2Kings 2021-07-19 20:08:18 -04:00
parent cbf7e116d7
commit 63f5cfee3a
4 changed files with 97 additions and 13 deletions

View File

@ -26,6 +26,7 @@ import android.webkit.WebView
import androidx.annotation.IdRes
import androidx.appcompat.graphics.drawable.DrawerArrowDrawable
import androidx.appcompat.widget.Toolbar
import androidx.core.animation.addListener
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import androidx.core.net.toUri
@ -79,6 +80,7 @@ import eu.kanade.tachiyomi.util.system.hasSideNavBar
import eu.kanade.tachiyomi.util.system.isBottomTappable
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.blurBehindWindow
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
import eu.kanade.tachiyomi.util.view.getItemView
import eu.kanade.tachiyomi.util.view.snack
@ -750,9 +752,12 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
if (overflowDialog != null) return false
val overflowDialog = OverflowDialog(this)
this.overflowDialog = overflowDialog
overflowDialog.setOnDismissListener {
this.overflowDialog = null
}
overflowDialog.blurBehindWindow(
window,
onDismiss = {
this.overflowDialog = null
}
)
overflowDialog.show()
}
else -> return super.onOptionsItemSelected(item)

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.main
import android.app.Dialog
import android.graphics.Color
import android.os.Build
import android.view.View
import android.view.ViewGroup
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
@ -25,7 +26,7 @@ class OverflowDialog(activity: MainActivity) : Dialog(activity, R.style.Overflow
setContentView(binding.root)
binding.touchOutside.setOnClickListener {
dismiss()
cancel()
}
val incogText = context.getString(R.string.incognito_mode)
with(binding.incognitoModeItem) {
@ -83,7 +84,7 @@ class OverflowDialog(activity: MainActivity) : Dialog(activity, R.style.Overflow
window.decorView.fitsSystemWindows = true
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility
.rem(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility
.rem(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR)
}

View File

@ -13,6 +13,8 @@ import android.content.Intent
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.Rect
import android.graphics.RenderEffect
import android.graphics.Shader
import android.graphics.drawable.BitmapDrawable
import android.os.Build
import android.os.Bundle
@ -1465,9 +1467,11 @@ class MangaDetailsController :
rightMargin = defMargin
bottomMargin = defMargin + binding.recycler.paddingBottom
}
val shortAnimationDuration = resources?.getInteger(
android.R.integer.config_shortAnimTime
) ?: 0
val shortAnimationDuration = (
resources?.getInteger(
android.R.integer.config_shortAnimTime
) ?: 0
).toLong()
// TransitionSet for the full cover because using animation for this SUCKS
val transitionSet = TransitionSet()
@ -1475,7 +1479,7 @@ class MangaDetailsController :
transitionSet.addTransition(bound)
val changeImageTransform = ChangeImageTransform()
transitionSet.addTransition(changeImageTransform)
transitionSet.duration = shortAnimationDuration.toLong()
transitionSet.duration = shortAnimationDuration
TransitionManager.beginDelayedTransition(binding.frameLayout, transitionSet)
// AnimationSet for backdrop because idk how to use TransitionSet
@ -1483,7 +1487,18 @@ class MangaDetailsController :
play(
ObjectAnimator.ofFloat(fullBackdrop, View.ALPHA, 0f, 0.5f)
)
duration = shortAnimationDuration.toLong()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
binding.swipeRefresh.setRenderEffect(
RenderEffect.createBlurEffect(
15f,
15f,
Shader.TileMode.MIRROR
)
)
}
duration = shortAnimationDuration
interpolator = DecelerateInterpolator()
addListener(
object : AnimatorListenerAdapter() {
@ -1524,13 +1539,16 @@ class MangaDetailsController :
transitionSet2.addTransition(bound2)
val changeImageTransform2 = ChangeImageTransform()
transitionSet2.addTransition(changeImageTransform2)
transitionSet2.duration = shortAnimationDuration.toLong()
transitionSet2.duration = shortAnimationDuration
TransitionManager.beginDelayedTransition(binding.frameLayout, transitionSet2)
// Animation to remove backdrop and hide the full cover
currentAnimator = AnimatorSet().apply {
play(ObjectAnimator.ofFloat(fullBackdrop, View.ALPHA, 0f))
duration = shortAnimationDuration.toLong()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
binding.swipeRefresh.setRenderEffect(null)
}
duration = shortAnimationDuration
interpolator = DecelerateInterpolator()
if (!activity.isInNightMode()) {

View File

@ -2,32 +2,42 @@
package eu.kanade.tachiyomi.util.view
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.DialogInterface
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.Point
import android.graphics.RenderEffect
import android.graphics.Shader
import android.os.Build
import android.view.Gravity
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.Window
import android.view.WindowInsets
import android.widget.Button
import android.widget.FrameLayout
import android.widget.TextView
import androidx.annotation.ColorRes
import androidx.annotation.FloatRange
import androidx.annotation.IdRes
import androidx.annotation.Px
import androidx.annotation.RequiresApi
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.widget.PopupMenu
import androidx.core.animation.addListener
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsAnimationCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.forEach
import androidx.interpolator.view.animation.FastOutLinearInInterpolator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSmoothScroller
import androidx.recyclerview.widget.RecyclerView
@ -45,7 +55,6 @@ import eu.kanade.tachiyomi.util.system.contextCompatColor
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.pxToDp
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import uy.kohesive.injekt.api.get
import kotlin.math.max
import kotlin.math.pow
import kotlin.math.roundToInt
@ -412,3 +421,54 @@ inline fun View.popupMenu(
popup.show()
return popup
}
fun Dialog.blurBehindWindow(
window: Window?,
blurAmount: Float = 20f,
onShow: DialogInterface.OnShowListener? = null,
onDismiss: DialogInterface.OnDismissListener? = null,
onCancel: DialogInterface.OnCancelListener? = null
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
setOnShowListener {
onShow?.onShow(it)
window?.decorView?.animateBlur(1f, blurAmount, 50)?.start()
}
setOnDismissListener {
onDismiss?.onDismiss(it)
window?.decorView?.animateBlur(blurAmount, 1f, 50, true)?.start()
}
setOnCancelListener {
onCancel?.onCancel(it)
window?.decorView?.animateBlur(blurAmount, 1f, 50, true)?.start()
}
}
}
@RequiresApi(31)
fun View.animateBlur(
@FloatRange(from = 0.1) from: Float,
@FloatRange(from = 0.1) to: Float,
duration: Long,
removeBlurAtEnd: Boolean = false
): ValueAnimator {
return ValueAnimator.ofFloat(from, to).apply {
interpolator = FastOutLinearInInterpolator()
this.duration = duration
addUpdateListener { animator ->
val amount = animator.animatedValue as Float
try {
setRenderEffect(
RenderEffect.createBlurEffect(amount, amount, Shader.TileMode.CLAMP)
)
} catch (_: Exception) {}
}
if (removeBlurAtEnd) {
addListener(
onEnd = {
setRenderEffect(null)
}
)
}
}
}