TachiyomiAppBarLayout: Use insetter to handle inset (#6506)

This requires adding the status bar foreground drawing logic since the parent
class wouldn't know the inset changes anymore.
This commit is contained in:
Ivan Iskandar 2022-01-28 22:14:13 +07:00 committed by GitHub
parent 08ad4f96b9
commit a68f123594
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,13 +6,16 @@ import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.animation.LinearInterpolator
import android.widget.TextView
import androidx.annotation.FloatRange
import androidx.lifecycle.coroutineScope
import androidx.lifecycle.findViewTreeLifecycleOwner
import com.google.android.material.animation.AnimationUtils
import com.google.android.material.shape.MaterialShapeDrawable
import dev.chrisbanes.insetter.applyInsetter
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.view.findChild
import kotlinx.coroutines.flow.launchIn
@ -50,28 +53,7 @@ class TachiyomiAppBarLayout @JvmOverloads constructor(
private var animatorSet: AnimatorSet? = null
private var statusBarForegroundAnimator: ValueAnimator? = null
private val offsetListener = OnOffsetChangedListener { appBarLayout, verticalOffset ->
// Show status bar foreground when offset
val foreground = (appBarLayout?.statusBarForeground as? MaterialShapeDrawable) ?: return@OnOffsetChangedListener
val start = foreground.alpha
val end = if (verticalOffset != 0) 255 else 0
statusBarForegroundAnimator?.cancel()
if (animatorSet?.isRunning == true) {
foreground.alpha = end
return@OnOffsetChangedListener
}
if (start != end) {
statusBarForegroundAnimator = ValueAnimator.ofInt(start, end).apply {
duration = resources.getInteger(R.integer.app_bar_elevation_anim_duration).toLong()
interpolator = AnimationUtils.LINEAR_INTERPOLATOR
addUpdateListener {
foreground.alpha = it.animatedValue as Int
}
start()
}
}
}
private var currentOffset = 0
var isTransparentWhenNotLifted = false
set(value) {
@ -100,9 +82,47 @@ class TachiyomiAppBarLayout @JvmOverloads constructor(
override fun setLiftedState(lifted: Boolean, force: Boolean): Boolean = false
override fun draw(canvas: Canvas) {
super.draw(canvas)
val saveCount = canvas.save()
canvas.translate(0f, -currentOffset.toFloat())
statusBarForeground?.draw(canvas)
canvas.restoreToCount(saveCount)
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
super.onLayout(changed, l, t, r, b)
statusBarForeground?.setBounds(0, 0, width, paddingTop)
}
override fun onOffsetChanged(offset: Int) {
currentOffset = offset
super.onOffsetChanged(offset)
// Show status bar foreground when offset
val foreground = (statusBarForeground as? MaterialShapeDrawable) ?: return
val start = foreground.alpha
val end = if (offset != 0) 255 else 0
statusBarForegroundAnimator?.cancel()
if (animatorSet?.isRunning == true) {
foreground.alpha = end
return
}
if (start != end) {
statusBarForegroundAnimator = ValueAnimator.ofInt(start, end).apply {
duration = resources.getInteger(R.integer.app_bar_elevation_anim_duration).toLong()
interpolator = LINEAR_INTERPOLATOR
addUpdateListener {
foreground.alpha = it.animatedValue as Int
}
start()
}
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
addOnOffsetChangedListener(offsetListener)
toolbar.background.alpha = 0 // Use app bar background
titleTextView = toolbar.findChild<TextView>()
@ -126,9 +146,9 @@ class TachiyomiAppBarLayout @JvmOverloads constructor(
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
removeOnOffsetChangedListener(offsetListener)
override fun setStatusBarForeground(drawable: Drawable?) {
super.setStatusBarForeground(drawable)
setWillNotDraw(statusBarForeground == null)
}
@SuppressLint("Recycle")
@ -168,7 +188,7 @@ class TachiyomiAppBarLayout @JvmOverloads constructor(
animatorSet?.cancel()
animatorSet = AnimatorSet().apply {
duration = resources.getInteger(R.integer.app_bar_elevation_anim_duration).toLong()
interpolator = AnimationUtils.LINEAR_INTERPOLATOR
interpolator = LINEAR_INTERPOLATOR
playTogether(*animators.toTypedArray())
start()
}
@ -177,5 +197,17 @@ class TachiyomiAppBarLayout @JvmOverloads constructor(
init {
statusBarForeground = MaterialShapeDrawable.createWithElevationOverlay(context)
applyInsetter {
type(navigationBars = true) {
margin(horizontal = true)
}
type(statusBars = true) {
padding(top = true)
}
}
}
companion object {
private val LINEAR_INTERPOLATOR = LinearInterpolator()
}
}