Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c30c4e14 authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Fade out/in header with customizer in/out

As the QSPanel doesn't reach the top of the screen, the
LargeScreenShadeHeader peeks out from behind the Edit screen
in certain configurations. In order to hide it, we fade it out/in
together with the circular reveal.

Test: manual
Test: atest NotificationQSContainerControllerTest
Test: atest LargeScreenShadeHeaderControllerTest
Test: atest LargeScreenShadeHeaderControllerCombinedTest
Fixes: 244455245
Change-Id: Ie8b8fb07b28e18b9620a948fbb6589394c4224d6
parent 9fefe95b
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -3,7 +3,9 @@ package com.android.systemui.plugins.qs
interface QSContainerController {
    fun setCustomizerAnimating(animating: Boolean)

    fun setCustomizerShowing(showing: Boolean)
    fun setCustomizerShowing(showing: Boolean) = setCustomizerShowing(showing, 0L)

    fun setCustomizerShowing(showing: Boolean, animationDuration: Long)

    fun setDetailShowing(showing: Boolean)
}
+12 −3
Original line number Diff line number Diff line
@@ -39,8 +39,15 @@ public class QSDetailClipper {
        mBackground = (TransitionDrawable) detail.getBackground();
    }

    public void animateCircularClip(int x, int y, boolean in, AnimatorListener listener) {
        updateCircularClip(true /* animate */, x, y, in, listener);
    /**
     * @param x x position where animation should originate
     * @param y y position where animation should originate
     * @param in whether animating in or out
     * @param listener Animation listener. Called whether or not {@code animate} is true.
     * @return the duration of the circular animator
     */
    public long animateCircularClip(int x, int y, boolean in, AnimatorListener listener) {
        return updateCircularClip(true /* animate */, x, y, in, listener);
    }

    /**
@@ -50,8 +57,9 @@ public class QSDetailClipper {
     * @param y y position where animation should originate
     * @param in whether animating in or out
     * @param listener Animation listener. Called whether or not {@code animate} is true.
     * @return the duration of the circular animator
     */
    public void updateCircularClip(boolean animate, int x, int y, boolean in,
    public long updateCircularClip(boolean animate, int x, int y, boolean in,
            AnimatorListener listener) {
        if (mAnimator != null) {
            mAnimator.cancel();
@@ -87,6 +95,7 @@ public class QSDetailClipper {
            mAnimator.addListener(mGoneOnEnd);
        }
        mAnimator.start();
        return mAnimator.getDuration();
    }

    private final Runnable mReverseBackground = new Runnable() {
+6 −4
Original line number Diff line number Diff line
@@ -125,9 +125,10 @@ public class QSCustomizer extends LinearLayout {
            isShown = true;
            mOpening = true;
            setVisibility(View.VISIBLE);
            mClipper.animateCircularClip(mX, mY, true, new ExpandAnimatorListener(tileAdapter));
            long duration = mClipper.animateCircularClip(
                    mX, mY, true, new ExpandAnimatorListener(tileAdapter));
            mQsContainerController.setCustomizerAnimating(true);
            mQsContainerController.setCustomizerShowing(true);
            mQsContainerController.setCustomizerShowing(true, duration);
        }
    }

@@ -153,13 +154,14 @@ public class QSCustomizer extends LinearLayout {
            // Make sure we're not opening (because we're closing). Nobody can think we are
            // customizing after the next two lines.
            mOpening = false;
            long duration = 0;
            if (animate) {
                mClipper.animateCircularClip(mX, mY, false, mCollapseAnimationListener);
                duration = mClipper.animateCircularClip(mX, mY, false, mCollapseAnimationListener);
            } else {
                setVisibility(View.GONE);
            }
            mQsContainerController.setCustomizerAnimating(animate);
            mQsContainerController.setCustomizerShowing(false);
            mQsContainerController.setCustomizerShowing(false, duration);
        }
    }

+9 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import androidx.constraintlayout.motion.widget.MotionLayout
import com.android.settingslib.Utils
import com.android.systemui.Dumpable
import com.android.systemui.R
import com.android.systemui.animation.Interpolators
import com.android.systemui.animation.ShadeInterpolation
import com.android.systemui.battery.BatteryMeterView
import com.android.systemui.battery.BatteryMeterViewController
@@ -310,6 +311,14 @@ class LargeScreenShadeHeaderController @Inject constructor(
        updateVisibility()
    }

    fun startCustomizingAnimation(show: Boolean, duration: Long) {
        header.animate()
                .setDuration(duration)
                .alpha(if (show) 0f else 1f)
                .setInterpolator(if (show) Interpolators.ALPHA_OUT else Interpolators.ALPHA_IN)
                .start()
    }

    private fun loadConstraints() {
        if (header is MotionLayout) {
            // Use resources.getXml instead of passing the resource id due to bug b/205018300
+7 −3
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ class NotificationsQSContainerController @Inject constructor(
    view: NotificationsQuickSettingsContainer,
    private val navigationModeController: NavigationModeController,
    private val overviewProxyService: OverviewProxyService,
    private val largeScreenShadeHeaderController: LargeScreenShadeHeaderController,
    private val featureFlags: FeatureFlags,
    @Main private val delayableExecutor: DelayableExecutor
) : ViewController<NotificationsQuickSettingsContainer>(view), QSContainerController {
@@ -156,10 +157,13 @@ class NotificationsQSContainerController @Inject constructor(
        }
    }

    override fun setCustomizerShowing(showing: Boolean) {
    override fun setCustomizerShowing(showing: Boolean, animationDuration: Long) {
        if (showing != isQSCustomizing) {
            isQSCustomizing = showing
            largeScreenShadeHeaderController.startCustomizingAnimation(showing, animationDuration)
            updateBottomSpacing()
        }
    }

    override fun setDetailShowing(showing: Boolean) {
        isQSDetailShowing = showing
Loading