OSDN Git Service

Added dissapear animation to pattern and pin input
authorSelim Cinek <cinek@google.com>
Tue, 11 Nov 2014 12:41:02 +0000 (13:41 +0100)
committerSelim Cinek <cinek@google.com>
Wed, 12 Nov 2014 13:48:48 +0000 (14:48 +0100)
Bug: 18232017
Change-Id: I062d55b0870ccaad6093b672f5076c3f80c10f94

12 files changed:
packages/Keyguard/res/layout-land/keyguard_host_view.xml
packages/Keyguard/res/layout-port/keyguard_host_view.xml
packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml
packages/Keyguard/res/layout/keyguard_bouncer.xml
packages/Keyguard/res/layout/keyguard_pattern_view.xml
packages/Keyguard/res/layout/keyguard_simple_host_view.xml
packages/Keyguard/src/com/android/keyguard/AppearAnimationCreator.java
packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java
packages/Keyguard/src/com/android/keyguard/DisappearAnimationUtils.java [new file with mode: 0644]
packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java

index 1d596d3..891910e 100644 (file)
     android:id="@+id/keyguard_host_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="horizontal">
+    android:orientation="horizontal"
+    android:clipChildren="false"
+    android:clipToPadding="false">
 
     <com.android.keyguard.MultiPaneChallengeLayout
         android:id="@+id/multi_pane_challenge"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="horizontal"
-        android:clipChildren="false">
+        android:clipChildren="false"
+        android:clipToPadding="false">
 
         <include layout="@layout/keyguard_widget_remove_drop_target"
             android:id="@+id/keyguard_widget_pager_delete_target"
index 8223db4..1b8820b 100644 (file)
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:gravity="center_horizontal"
+    android:clipChildren="false"
+    android:clipToPadding="false"
     android:orientation="vertical">
 
     <com.android.keyguard.SlidingChallengeLayout
         android:id="@+id/sliding_layout"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:clipChildren="false">
+        android:clipChildren="false"
+        android:clipToPadding="false">
 
         <FrameLayout
             android:layout_width="match_parent"
index ba2f3a6..f2f3981 100644 (file)
     android:id="@+id/keyguard_host_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="horizontal">
+    android:orientation="horizontal"
+    android:clipChildren="false"
+    android:clipToPadding="false">
 
     <com.android.keyguard.MultiPaneChallengeLayout
         android:id="@+id/multi_pane_challenge"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:clipChildren="false"
+        android:clipToPadding="false"
         android:orientation="vertical">
 
         <include layout="@layout/keyguard_widget_remove_drop_target"
index 3c1f65e..296efb3 100644 (file)
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@android:color/transparent"
+    android:clipChildren="false"
+    android:clipToPadding="false"
     android:fitsSystemWindows="true">
 
     <include
         style="@style/BouncerSecurityContainer"
         layout="@layout/keyguard_simple_host_view"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
+        android:layout_height="wrap_content" />
 </FrameLayout>
 
index bd585b5..1fb0420 100644 (file)
@@ -27,6 +27,8 @@
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:clipChildren="false"
+    android:clipToPadding="false"
     androidprv:layout_maxWidth="@dimen/keyguard_security_width"
     androidprv:layout_maxHeight="@dimen/keyguard_security_height"
     android:gravity="center_horizontal"
 
     <FrameLayout
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="match_parent"
+        android:clipChildren="false"
+        android:clipToPadding="false">
 
         <LinearLayout
             android:layout_height="wrap_content"
             android:layout_width="wrap_content"
             android:orientation="vertical"
-            android:layout_gravity="center_horizontal|bottom">
+            android:layout_gravity="center_horizontal|bottom"
+            android:clipChildren="false"
+            android:clipToPadding="false">
 
             <include layout="@layout/keyguard_message_area"
                 android:layout_width="match_parent"
@@ -52,6 +58,8 @@
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
+             android:clipChildren="false"
+             android:clipToPadding="false"
              >
             <com.android.internal.widget.LockPatternView
                 android:id="@+id/lockPatternView"
@@ -63,7 +71,9 @@
                 android:layout_marginStart="8dip"
                 android:layout_gravity="center_horizontal"
                 android:gravity="center"
-                android:contentDescription="@string/keyguard_accessibility_pattern_area" />
+                android:contentDescription="@string/keyguard_accessibility_pattern_area"
+                android:clipChildren="false"
+                android:clipToPadding="false" />
           </FrameLayout>
           <include layout="@layout/keyguard_eca"
               android:id="@+id/keyguard_selector_fade_container"
index 4336e1c..28ce265 100644 (file)
@@ -24,7 +24,9 @@
     xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_host_view"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:clipChildren="false"
+    android:clipToPadding="false">
 
     <com.android.keyguard.KeyguardSecurityContainer
         android:id="@+id/keyguard_security_container"
index 0d30ea6..3ff2cc0 100644 (file)
@@ -25,5 +25,6 @@ import android.view.animation.Interpolator;
  */
 public interface AppearAnimationCreator<T> {
      void createAnimation(T animatedObject, long delay, long duration,
-            float startTranslationY, Interpolator interpolator, Runnable finishListener);
+             float translationY, boolean appearing, Interpolator interpolator,
+             Runnable finishListener);
 }
index b685c73..9045fe3 100644 (file)
@@ -31,8 +31,10 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
     private final Interpolator mInterpolator;
     private final float mStartTranslation;
     private final AppearAnimationProperties mProperties = new AppearAnimationProperties();
-    private final float mDelayScale;
+    protected final float mDelayScale;
     private final long mDuration;
+    protected boolean mScaleTranslationWithRow;
+    protected boolean mAppearing;
 
     public AppearAnimationUtils(Context ctx) {
         this(ctx, DEFAULT_APPEAR_DURATION,
@@ -47,23 +49,25 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
                 R.dimen.appear_y_translation_start) * translationScaleFactor;
         mDelayScale = delayScaleFactor;
         mDuration = duration;
+        mScaleTranslationWithRow = false;
+        mAppearing = true;
     }
 
-    public void startAppearAnimation(View[][] objects, final Runnable finishListener) {
-        startAppearAnimation(objects, finishListener, this);
+    public void startAnimation(View[][] objects, final Runnable finishListener) {
+        startAnimation(objects, finishListener, this);
     }
 
-    public void startAppearAnimation(View[] objects, final Runnable finishListener) {
-        startAppearAnimation(objects, finishListener, this);
+    public void startAnimation(View[] objects, final Runnable finishListener) {
+        startAnimation(objects, finishListener, this);
     }
 
-    public <T> void startAppearAnimation(T[][] objects, final Runnable finishListener,
+    public <T> void startAnimation(T[][] objects, final Runnable finishListener,
             AppearAnimationCreator<T> creator) {
         AppearAnimationProperties properties = getDelays(objects);
         startAnimations(properties, objects, finishListener, creator);
     }
 
-    public <T> void startAppearAnimation(T[] objects, final Runnable finishListener,
+    public <T> void startAnimation(T[] objects, final Runnable finishListener,
             AppearAnimationCreator<T> creator) {
         AppearAnimationProperties properties = getDelays(objects);
         startAnimations(properties, objects, finishListener, creator);
@@ -83,7 +87,7 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
                 endRunnable = finishListener;
             }
             creator.createAnimation(objects[row], delay, mDuration,
-                    mStartTranslation, mInterpolator, endRunnable);
+                    mStartTranslation, true /* appearing */, mInterpolator, endRunnable);
         }
     }
 
@@ -95,6 +99,10 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
         }
         for (int row = 0; row < properties.delays.length; row++) {
             long[] columns = properties.delays[row];
+            float translation = mScaleTranslationWithRow
+                    ? (float) (Math.pow((properties.delays.length - row), 2)
+                    / properties.delays.length * mStartTranslation)
+                    : mStartTranslation;
             for (int col = 0; col < columns.length; col++) {
                 long delay = columns[col];
                 Runnable endRunnable = null;
@@ -102,7 +110,8 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
                     endRunnable = finishListener;
                 }
                 creator.createAnimation(objects[row][col], delay, mDuration,
-                        mStartTranslation, mInterpolator, endRunnable);
+                        mAppearing ? translation : -translation,
+                        mAppearing, mInterpolator, endRunnable);
             }
         }
     }
@@ -146,7 +155,7 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
         return mProperties;
     }
 
-    private long calculateDelay(int row, int col) {
+    protected long calculateDelay(int row, int col) {
         return (long) ((row * 40 + col * (Math.pow(row, 0.4) + 0.4) * 20) * mDelayScale);
     }
 
@@ -159,14 +168,14 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
     }
 
     @Override
-    public void createAnimation(View view, long delay, long duration, float startTranslationY,
-            Interpolator interpolator, Runnable endRunnable) {
+    public void createAnimation(View view, long delay, long duration, float translationY,
+            boolean appearing, Interpolator interpolator, Runnable endRunnable) {
         if (view != null) {
-            view.setAlpha(0f);
-            view.setTranslationY(startTranslationY);
+            view.setAlpha(appearing ? 0f : 1.0f);
+            view.setTranslationY(appearing ? translationY : 0);
             view.animate()
-                    .alpha(1f)
-                    .translationY(0)
+                    .alpha(appearing ? 1f : 0f)
+                    .translationY(appearing ? 0 : translationY)
                     .setInterpolator(interpolator)
                     .setDuration(duration)
                     .setStartDelay(delay);
diff --git a/packages/Keyguard/src/com/android/keyguard/DisappearAnimationUtils.java b/packages/Keyguard/src/com/android/keyguard/DisappearAnimationUtils.java
new file mode 100644 (file)
index 0000000..6fff0ba
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard;
+
+import android.content.Context;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+
+/**
+ * A class to make nice disappear transitions for views in a tabular layout.
+ */
+public class DisappearAnimationUtils extends AppearAnimationUtils {
+
+    public DisappearAnimationUtils(Context ctx) {
+        this(ctx, DEFAULT_APPEAR_DURATION,
+                1.0f, 1.0f,
+                AnimationUtils.loadInterpolator(ctx, android.R.interpolator.linear_out_slow_in));
+    }
+
+    public DisappearAnimationUtils(Context ctx, long duration, float translationScaleFactor,
+            float delayScaleFactor, Interpolator interpolator) {
+        super(ctx, duration, translationScaleFactor, delayScaleFactor, interpolator);
+        mScaleTranslationWithRow = true;
+        mAppearing = false;
+    }
+
+    protected long calculateDelay(int row, int col) {
+        return (long) ((row * 60 + col * (Math.pow(row, 0.4) + 0.4) * 10) * mDelayScale);
+    }
+}
index 55538a7..04ef57e 100644 (file)
@@ -28,6 +28,7 @@ import android.view.animation.AnimationUtils;
 public class KeyguardPINView extends KeyguardPinBasedInputView {
 
     private final AppearAnimationUtils mAppearAnimationUtils;
+    private final DisappearAnimationUtils mDisappearAnimationUtils;
     private ViewGroup mKeyguardBouncerFrame;
     private ViewGroup mRow0;
     private ViewGroup mRow1;
@@ -35,6 +36,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
     private ViewGroup mRow3;
     private View mDivider;
     private int mDisappearYTranslation;
+    private View[][] mViews;
 
     public KeyguardPINView(Context context) {
         this(context, null);
@@ -43,6 +45,10 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
     public KeyguardPINView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mAppearAnimationUtils = new AppearAnimationUtils(context);
+        mDisappearAnimationUtils = new DisappearAnimationUtils(context,
+                125, 0.6f /* translationScale */,
+                0.6f /* delayScale */, AnimationUtils.loadInterpolator(
+                        mContext, android.R.interpolator.fast_out_linear_in));
         mDisappearYTranslation = getResources().getDimensionPixelSize(
                 R.dimen.disappear_y_translation);
     }
@@ -71,6 +77,28 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
         mRow2 = (ViewGroup) findViewById(R.id.row2);
         mRow3 = (ViewGroup) findViewById(R.id.row3);
         mDivider = findViewById(R.id.divider);
+        mViews = new View[][]{
+                new View[]{
+                        mRow0, null, null
+                },
+                new View[]{
+                        findViewById(R.id.key1), findViewById(R.id.key2),
+                        findViewById(R.id.key3)
+                },
+                new View[]{
+                        findViewById(R.id.key4), findViewById(R.id.key5),
+                        findViewById(R.id.key6)
+                },
+                new View[]{
+                        findViewById(R.id.key7), findViewById(R.id.key8),
+                        findViewById(R.id.key9)
+                },
+                new View[]{
+                        null, findViewById(R.id.key0), findViewById(R.id.key_enter)
+                },
+                new View[]{
+                        null, mEcaView, null
+                }};
     }
 
     @Override
@@ -91,25 +119,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
                 .setDuration(500)
                 .setInterpolator(mAppearAnimationUtils.getInterpolator())
                 .translationY(0);
-        mAppearAnimationUtils.startAppearAnimation(new View[][] {
-                new View[] {
-                        mRow0, null, null
-                },
-                new View[] {
-                        findViewById(R.id.key1), findViewById(R.id.key2), findViewById(R.id.key3)
-                },
-                new View[] {
-                        findViewById(R.id.key4), findViewById(R.id.key5), findViewById(R.id.key6)
-                },
-                new View[] {
-                        findViewById(R.id.key7), findViewById(R.id.key8), findViewById(R.id.key9)
-                },
-                new View[] {
-                        null, findViewById(R.id.key0), findViewById(R.id.key_enter)
-                },
-                new View[] {
-                        null, mEcaView, null
-                }},
+        mAppearAnimationUtils.startAnimation(mViews,
                 new Runnable() {
                     @Override
                     public void run() {
@@ -119,14 +129,23 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
     }
 
     @Override
-    public boolean startDisappearAnimation(Runnable finishRunnable) {
+    public boolean startDisappearAnimation(final Runnable finishRunnable) {
+        enableClipping(false);
+        setTranslationY(0);
         animate()
-                .alpha(0f)
-                .translationY(mDisappearYTranslation)
-                .setInterpolator(AnimationUtils
-                        .loadInterpolator(mContext, android.R.interpolator.fast_out_linear_in))
-                .setDuration(100)
-                .withEndAction(finishRunnable);
+                .setDuration(280)
+                .setInterpolator(mDisappearAnimationUtils.getInterpolator())
+                .translationY(mDisappearYTranslation);
+        mDisappearAnimationUtils.startAnimation(mViews,
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        enableClipping(true);
+                        if (finishRunnable != null) {
+                            finishRunnable.run();
+                        }
+                    }
+                });
         return true;
     }
 
index 0e01a27..3212eec 100644 (file)
@@ -55,6 +55,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
 
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final AppearAnimationUtils mAppearAnimationUtils;
+    private final DisappearAnimationUtils mDisappearAnimationUtils;
 
     private CountDownTimer mCountdownTimer = null;
     private LockPatternUtils mLockPatternUtils;
@@ -99,9 +100,13 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
         super(context, attrs);
         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
         mAppearAnimationUtils = new AppearAnimationUtils(context,
-                AppearAnimationUtils.DEFAULT_APPEAR_DURATION, 1.5f /* delayScale */,
-                2.0f /* transitionScale */, AnimationUtils.loadInterpolator(
+                AppearAnimationUtils.DEFAULT_APPEAR_DURATION, 1.5f /* translationScale */,
+                2.0f /* delayScale */, AnimationUtils.loadInterpolator(
                         mContext, android.R.interpolator.linear_out_slow_in));
+        mDisappearAnimationUtils = new DisappearAnimationUtils(context,
+                125, 1.2f /* translationScale */,
+                0.8f /* delayScale */, AnimationUtils.loadInterpolator(
+                        mContext, android.R.interpolator.fast_out_linear_in));
         mDisappearYTranslation = getResources().getDimensionPixelSize(
                 R.dimen.disappear_y_translation);
     }
@@ -303,7 +308,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
                 .setDuration(500)
                 .setInterpolator(mAppearAnimationUtils.getInterpolator())
                 .translationY(0);
-        mAppearAnimationUtils.startAppearAnimation(
+        mAppearAnimationUtils.startAnimation(
                 mLockPatternView.getCellStates(),
                 new Runnable() {
                     @Override
@@ -316,21 +321,39 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
             mAppearAnimationUtils.createAnimation(mHelpMessage, 0,
                     AppearAnimationUtils.DEFAULT_APPEAR_DURATION,
                     mAppearAnimationUtils.getStartTranslation(),
+                    true /* appearing */,
                     mAppearAnimationUtils.getInterpolator(),
                     null /* finishRunnable */);
         }
     }
 
     @Override
-    public boolean startDisappearAnimation(Runnable finishRunnable) {
+    public boolean startDisappearAnimation(final Runnable finishRunnable) {
         mLockPatternView.clearPattern();
+        enableClipping(false);
+        setTranslationY(0);
         animate()
-                .alpha(0f)
-                .translationY(mDisappearYTranslation)
-                .setInterpolator(AnimationUtils.loadInterpolator(
-                        mContext, android.R.interpolator.fast_out_linear_in))
-                .setDuration(100)
-                .withEndAction(finishRunnable);
+                .setDuration(300)
+                .setInterpolator(mDisappearAnimationUtils.getInterpolator())
+                .translationY(-mDisappearAnimationUtils.getStartTranslation());
+        mDisappearAnimationUtils.startAnimation(mLockPatternView.getCellStates(),
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        enableClipping(true);
+                        if (finishRunnable != null) {
+                            finishRunnable.run();
+                        }
+                    }
+                }, KeyguardPatternView.this);
+        if (!TextUtils.isEmpty(mHelpMessage.getText())) {
+            mDisappearAnimationUtils.createAnimation(mHelpMessage, 0,
+                    200,
+                    - mDisappearAnimationUtils.getStartTranslation() * 3,
+                    false /* appearing */,
+                    mDisappearAnimationUtils.getInterpolator(),
+                    null /* finishRunnable */);
+        }
         return true;
     }
 
@@ -342,11 +365,15 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
 
     @Override
     public void createAnimation(final LockPatternView.CellState animatedCell, long delay,
-            long duration, float startTranslationY, Interpolator interpolator,
+            long duration, float translationY, final boolean appearing,
+            Interpolator interpolator,
             final Runnable finishListener) {
-        animatedCell.scale = 0.0f;
-        animatedCell.translateY = startTranslationY;
-        ValueAnimator animator = ValueAnimator.ofFloat(startTranslationY, 0.0f);
+        if (appearing) {
+            animatedCell.scale = 0.0f;
+        }
+        animatedCell.translateY = appearing ? translationY : 0;
+        ValueAnimator animator = ValueAnimator.ofFloat(animatedCell.translateY,
+                appearing ? 0 : translationY);
         animator.setInterpolator(interpolator);
         animator.setDuration(duration);
         animator.setStartDelay(delay);
@@ -354,7 +381,11 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
                 float animatedFraction = animation.getAnimatedFraction();
-                animatedCell.scale = animatedFraction;
+                if (appearing) {
+                    animatedCell.scale = animatedFraction;
+                } else {
+                    animatedCell.alpha = 1 - animatedFraction;
+                }
                 animatedCell.translateY = (float) animation.getAnimatedValue();
                 mLockPatternView.invalidate();
             }
@@ -368,8 +399,8 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
             });
 
             // Also animate the Emergency call
-            mAppearAnimationUtils.createAnimation(mEcaView, delay, duration, startTranslationY,
-            interpolator, null);
+            mAppearAnimationUtils.createAnimation(mEcaView, delay, duration, translationY,
+                    appearing, interpolator, null);
         }
         animator.start();
         mLockPatternView.invalidate();
index 297ff70..c71bccd 100644 (file)
@@ -145,7 +145,7 @@ public class KeyguardUserSwitcher {
         }
         mUserSwitcher.setClipChildren(false);
         mUserSwitcher.setClipToPadding(false);
-        mAppearAnimationUtils.startAppearAnimation(objects, new Runnable() {
+        mAppearAnimationUtils.startAnimation(objects, new Runnable() {
             @Override
             public void run() {
                 mUserSwitcher.setClipChildren(true);