Explorar o código

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.
Ivan Iskandar %!s(int64=3) %!d(string=hai) anos
pai
achega
a68f123594

+ 60 - 28
app/src/main/java/eu/kanade/tachiyomi/widget/TachiyomiAppBarLayout.kt

@@ -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()
     }
 }