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

Commit 42310965 authored by Christian Robertson's avatar Christian Robertson Committed by Dan Sandler
Browse files

Customized ripple animation for navigation bar

To implement the new gel-cap shaped ripple I resurrected the
onDraw and setPressed methods from the KitKat implementation.
The KitKat animation timings were adjusted to match the material
ripple, but the structure of the animators is the same as KitKat.

Since the new ripple is drawn directly to the canvas, the references
to the KitKat background image were removed.

The LogInterpolator is copied from the framework Ripple
to match the material animation curves.

Bug: 17112935
Change-Id: If6a3eb92de794b526338166bf8cb096eb9764cf6
parent 6f90967b
Loading
Loading
Loading
Loading
+3 −14
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@
                android:src="@drawable/ic_sysbar_back"
                systemui:keyCode="4"
                android:layout_weight="0"
                android:background="@drawable/ripple_drawable"
                android:contentDescription="@string/accessibility_back"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
@@ -69,7 +68,6 @@
                systemui:keyCode="3"
                systemui:keyRepeat="true"
                android:layout_weight="0"
                android:background="@drawable/ripple_drawable"
                android:contentDescription="@string/accessibility_home"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
@@ -77,7 +75,6 @@
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_recent"
                android:layout_weight="0"
                android:background="@drawable/ripple_drawable"
                android:contentDescription="@string/accessibility_recent"
                />
            <Space 
@@ -98,7 +95,6 @@
                    systemui:keyCode="82"
                    android:visibility="invisible"
                    android:contentDescription="@string/accessibility_menu"
                    android:background="@drawable/ripple_drawable"
                    />
                <com.android.systemui.statusbar.policy.KeyButtonView
                    android:id="@+id/ime_switcher"
@@ -108,8 +104,7 @@
                    android:scaleType="centerInside"
                    android:src="@drawable/ic_ime_switcher_default"
                    android:visibility="invisible"
                    android:contentDescription="@string/accessibility_ime_switch_button"
                    android:background="@drawable/ripple_drawable" />
                    android:contentDescription="@string/accessibility_ime_switch_button" />
            </FrameLayout>
        </LinearLayout>

@@ -205,7 +200,6 @@
                android:src="@drawable/ic_sysbar_back"
                systemui:keyCode="4"
                android:layout_weight="0"
                android:background="@drawable/ripple_drawable"
                android:contentDescription="@string/accessibility_back"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
@@ -215,7 +209,6 @@
                systemui:keyCode="3"
                systemui:keyRepeat="true"
                android:layout_weight="0"
                android:background="@drawable/ripple_drawable"
                android:contentDescription="@string/accessibility_home"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
@@ -223,7 +216,6 @@
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_recent"
                android:layout_weight="0"
                android:background="@drawable/ripple_drawable"
                android:contentDescription="@string/accessibility_recent"
                />
            <Space 
@@ -243,9 +235,7 @@
                    android:src="@drawable/ic_sysbar_menu"
                    systemui:keyCode="82"
                    android:visibility="invisible"
                    android:contentDescription="@string/accessibility_menu"
                    android:background="@drawable/ripple_drawable"
                    />
                    android:contentDescription="@string/accessibility_menu" />
                <com.android.systemui.statusbar.policy.KeyButtonView
                    android:id="@+id/ime_switcher"
                    android:layout_width="@dimen/navigation_extra_key_width"
@@ -254,8 +244,7 @@
                    android:src="@drawable/ic_ime_switcher_default"
                    android:visibility="invisible"
                    android:contentDescription="@string/accessibility_ime_switch_button"
                    android:scaleType="centerInside"
                    android:background="@drawable/ripple_drawable" />
                    android:scaleType="centerInside" />
            </FrameLayout>
        </LinearLayout>

+2 −12
Original line number Diff line number Diff line
@@ -55,7 +55,6 @@
                systemui:keyCode="4"
                android:layout_weight="0"
                android:scaleType="center"
                android:background="@drawable/ripple_drawable"
                android:contentDescription="@string/accessibility_back"
                />
            <View 
@@ -71,7 +70,6 @@
                systemui:keyCode="3"
                systemui:keyRepeat="false"
                android:layout_weight="0"
                android:background="@drawable/ripple_drawable"
                android:contentDescription="@string/accessibility_home"
                />
            <View 
@@ -85,7 +83,6 @@
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_recent"
                android:layout_weight="0"
                android:background="@drawable/ripple_drawable"
                android:contentDescription="@string/accessibility_recent"
                />
            <FrameLayout
@@ -99,7 +96,6 @@
                    android:contentDescription="@string/accessibility_menu"
                    android:src="@drawable/ic_sysbar_menu"
                    android:visibility="invisible"
                    android:background="@drawable/ripple_drawable"
                    systemui:keyCode="82" />

                <com.android.systemui.statusbar.policy.KeyButtonView
@@ -109,8 +105,7 @@
                    android:contentDescription="@string/accessibility_ime_switch_button"
                    android:scaleType="centerInside"
                    android:src="@drawable/ic_ime_switcher_default"
                    android:visibility="invisible"
                    android:background="@drawable/ripple_drawable" />
                    android:visibility="invisible" />
            </FrameLayout>

        </LinearLayout>
@@ -202,8 +197,7 @@
                    android:contentDescription="@string/accessibility_ime_switch_button"
                    android:scaleType="centerInside"
                    android:src="@drawable/ic_ime_switcher_default"
                    android:visibility="invisible"
                    android:background="@drawable/ripple_drawable" />
                    android:visibility="invisible" />

                <com.android.systemui.statusbar.policy.KeyButtonView
                    android:id="@+id/menu"
@@ -212,7 +206,6 @@
                    android:contentDescription="@string/accessibility_menu"
                    android:src="@drawable/ic_sysbar_menu_land"
                    android:visibility="invisible"
                    android:background="@drawable/ripple_drawable"
                    systemui:keyCode="82" />
            </FrameLayout>

@@ -222,7 +215,6 @@
                android:src="@drawable/ic_sysbar_recent_land"
                android:layout_weight="0"
                android:contentDescription="@string/accessibility_recent"
                android:background="@drawable/ripple_drawable"
                />
            <View 
                android:layout_height="match_parent"
@@ -238,7 +230,6 @@
                systemui:keyRepeat="false"
                android:layout_weight="0"
                android:contentDescription="@string/accessibility_home"
                android:background="@drawable/ripple_drawable"
                />
            <View 
                android:layout_height="match_parent"
@@ -254,7 +245,6 @@
                systemui:keyCode="4"
                android:layout_weight="0"
                android:contentDescription="@string/accessibility_back"
                android:background="@drawable/ripple_drawable"
                />
            <View
                android:layout_height="40dp"
+122 −29
Original line number Diff line number Diff line
@@ -17,11 +17,15 @@
package com.android.systemui.statusbar.policy;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.hardware.input.InputManager;
import android.media.AudioManager;
import android.os.Bundle;
@@ -34,10 +38,12 @@ import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
import java.lang.Math;

import com.android.systemui.R;

@@ -50,15 +56,21 @@ public class KeyButtonView extends ImageView {

    // TODO: Get rid of this
    public static final float DEFAULT_QUIESCENT_ALPHA = 1f;
    public static final float MAX_ALPHA = 0.15f;
    public static final float GLOW_MAX_SCALE_FACTOR = 1.5f;

    private long mDownTime;
    private int mCode;
    private int mTouchSlop;
    private float mGlowAlpha = 0f;
    private float mGlowScale = 1f;
    private float mDrawingAlpha = 1f;
    private float mQuiescentAlpha = DEFAULT_QUIESCENT_ALPHA;
    private boolean mSupportsLongpress = true;
    private AnimatorSet mPressedAnim;
    private Animator mAnimateToQuiescent = new ObjectAnimator();
    private Drawable mBackground;
    private Paint mRipplePaint;
    private final TimeInterpolator mInterpolator = (TimeInterpolator) new LogInterpolator();
    private AudioManager mAudioManager;

    private final Runnable mCheckLongPress = new Runnable() {
@@ -90,11 +102,6 @@ public class KeyButtonView extends ImageView {

        mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true);

        Drawable d = getBackground();
        if (d != null) {
            mBackground = d.mutate();
            setBackground(mBackground);
        }

        setDrawingAlpha(mQuiescentAlpha);

@@ -134,13 +141,45 @@ public class KeyButtonView extends ImageView {
        return super.performAccessibilityAction(action, arguments);
    }

    private Paint getRipplePaint() {
        if (mRipplePaint == null) {
            mRipplePaint = new Paint();
            mRipplePaint.setAntiAlias(true);
            mRipplePaint.setColor(0xffffffff);
        }
        return mRipplePaint;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        final Paint p = getRipplePaint();
        p.setAlpha((int)(MAX_ALPHA * mDrawingAlpha * mGlowAlpha * 255));

        final float w = getWidth();
        final float h = getHeight();
        final boolean horizontal = w > h;
        final float diameter = (horizontal ? w : h) * mGlowScale;
        final float radius = diameter * .5f;
        final float cx = w * .5f;
        final float cy = h * .5f;
        final float rx = horizontal ? radius : cx;
        final float ry = horizontal ? cy : radius;
        final float corner = horizontal ? cy : cx;

        canvas.drawRoundRect(cx - rx, cy - ry,
                             cx + rx, cy + ry,
                             corner, corner, p);

        super.onDraw(canvas);
    }

    public void setQuiescentAlpha(float alpha, boolean animate) {
        mAnimateToQuiescent.cancel();
        alpha = Math.min(Math.max(alpha, 0), 1);
        if (alpha == mQuiescentAlpha && alpha == mDrawingAlpha) return;
        mQuiescentAlpha = alpha;
        if (DEBUG) Log.d(TAG, "New quiescent alpha = " + mQuiescentAlpha);
        if (mBackground != null && animate) {
        if (animate) {
            mAnimateToQuiescent = animateToQuiescent();
            mAnimateToQuiescent.start();
        } else {
@@ -162,34 +201,79 @@ public class KeyButtonView extends ImageView {

    public void setDrawingAlpha(float x) {
        setImageAlpha((int) (x * 255));
        if (mBackground != null) {
            mBackground.setAlpha((int)(x * 255));
        }
        mDrawingAlpha = x;
    }

    public float getGlowAlpha() {
        return mGlowAlpha;
    }

    public void setGlowAlpha(float x) {
        mGlowAlpha = x;
        invalidate();
    }

    public float getGlowScale() {
        return mGlowScale;
    }

    public void setGlowScale(float x) {
        mGlowScale = x;
        final float w = getWidth();
        final float h = getHeight();
        if (GLOW_MAX_SCALE_FACTOR <= 1.0f) {
            // this only works if we know the glow will never leave our bounds
            invalidate();
        } else {
            final float rx = (w * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
            final float ry = (h * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
            com.android.systemui.SwipeHelper.invalidateGlobalRegion(
                    this,
                    new RectF(getLeft() - rx,
                              getTop() - ry,
                              getRight() + rx,
                              getBottom() + ry));

            // also invalidate our immediate parent to help avoid situations where nearby glows
            // interfere
            ((View)getParent()).invalidate();
        }
    }

    public void setPressed(boolean pressed) {
        if (mBackground != null) {
        if (pressed != isPressed()) {
            if (mPressedAnim != null && mPressedAnim.isRunning()) {
                mPressedAnim.cancel();
            }
            final AnimatorSet as = mPressedAnim = new AnimatorSet();
            final ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(this,
                    "glowScale", GLOW_MAX_SCALE_FACTOR);
            scaleAnimator.setInterpolator(mInterpolator);
            if (pressed) {
                mGlowScale = 0f;
                if (mGlowAlpha < mQuiescentAlpha)
                    mGlowAlpha = mQuiescentAlpha;
                setDrawingAlpha(1f);
                as.playTogether(
                    ObjectAnimator.ofFloat(this, "glowAlpha", 1f),
                    scaleAnimator
                );
                as.setDuration(500);
            } else {
                mAnimateToQuiescent.cancel();
                mAnimateToQuiescent = animateToQuiescent();
                    mAnimateToQuiescent.setDuration(500);
                    mAnimateToQuiescent.start();
                }
                as.playTogether(
                    ObjectAnimator.ofFloat(this, "glowAlpha", mGlowAlpha, mGlowAlpha * .2f, 0f),
                    scaleAnimator,
                    mAnimateToQuiescent
                );
                as.setDuration(500);
            }
            as.start();
        }
        super.setPressed(pressed);
    }

    private void setHotspot(float x, float y) {
        if (mBackground != null) {
            mBackground.setHotspot(x, y);
        }
    }

    public boolean onTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();
        int x, y;
@@ -209,7 +293,6 @@ public class KeyButtonView extends ImageView {
                    removeCallbacks(mCheckLongPress);
                    postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
                }
                setHotspot(ev.getX(), ev.getY());
                break;
            case MotionEvent.ACTION_MOVE:
                x = (int)ev.getX();
@@ -218,7 +301,6 @@ public class KeyButtonView extends ImageView {
                        && x < getWidth() + mTouchSlop
                        && y >= -mTouchSlop
                        && y < getHeight() + mTouchSlop);
                setHotspot(ev.getX(), ev.getY());
                break;
            case MotionEvent.ACTION_CANCEL:
                setPressed(false);
@@ -272,6 +354,17 @@ public class KeyButtonView extends ImageView {
        InputManager.getInstance().injectInputEvent(ev,
                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
    }

    /**
    * Interpolator with a smooth log deceleration
    */
    private static final class LogInterpolator implements TimeInterpolator {
        @Override
        public float getInterpolation(float input) {
            return 1 - (float) Math.pow(400, -input * 1.4);
        }
    }

}