Merge "Appear animation for PIN view." into lmp-preview-dev
This commit is contained in:
@@ -41,28 +41,16 @@
|
||||
android:layout_weight="1"
|
||||
android:layoutDirection="ltr"
|
||||
>
|
||||
<LinearLayout
|
||||
<RelativeLayout
|
||||
android:id="@+id/row0"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_weight="1"
|
||||
>
|
||||
<TextView android:id="@+id/pinEntry"
|
||||
android:editable="true"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
|
||||
android:singleLine="true"
|
||||
android:cursorVisible="false"
|
||||
android:background="@null"
|
||||
android:textAppearance="@style/TextAppearance.NumPadKey"
|
||||
android:imeOptions="flagForceAscii|actionDone"
|
||||
/>
|
||||
<ImageButton android:id="@+id/delete_button"
|
||||
<ImageButton android:id="@+id/delete_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:gravity="center_vertical"
|
||||
android:src="@drawable/ic_input_delete"
|
||||
android:clickable="true"
|
||||
@@ -73,13 +61,30 @@
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/keyboardview_keycode_delete"
|
||||
/>
|
||||
</LinearLayout>
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="1dp"
|
||||
android:background="#55FFFFFF"
|
||||
/>
|
||||
<TextView android:id="@+id/pinEntry"
|
||||
android:editable="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toStartOf="@+id/delete_button"
|
||||
android:layout_alignParentStart="true"
|
||||
android:gravity="center"
|
||||
android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
|
||||
android:singleLine="true"
|
||||
android:cursorVisible="false"
|
||||
android:background="@null"
|
||||
android:textAppearance="@style/TextAppearance.NumPadKey"
|
||||
android:imeOptions="flagForceAscii|actionDone"
|
||||
/>
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="#55FFFFFF"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/row1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
@@ -114,6 +119,7 @@
|
||||
/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/row2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
@@ -148,6 +154,7 @@
|
||||
/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/row3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="horizontal"
|
||||
@@ -182,6 +189,7 @@
|
||||
/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/row4"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
|
||||
@@ -161,4 +161,6 @@
|
||||
<dimen name="widget_big_font_size">68dp</dimen>
|
||||
<dimen name="big_font_size">120dp</dimen>
|
||||
|
||||
<!-- The y translation to apply at the start in appear animations. -->
|
||||
<dimen name="appear_y_translation_start">24dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
/**
|
||||
* A class to make nice appear transitions for views in a tabular layout.
|
||||
*/
|
||||
public class AppearAnimationUtils {
|
||||
|
||||
public static final long APPEAR_DURATION = 220;
|
||||
|
||||
private final Interpolator mLinearOutSlowIn;
|
||||
private final float mStartTranslation;
|
||||
|
||||
public AppearAnimationUtils(Context ctx) {
|
||||
mLinearOutSlowIn = AnimationUtils.loadInterpolator(
|
||||
ctx, android.R.interpolator.linear_out_slow_in);
|
||||
mStartTranslation =
|
||||
ctx.getResources().getDimensionPixelOffset(R.dimen.appear_y_translation_start);
|
||||
}
|
||||
|
||||
public void startAppearAnimation(View[][] views, final Runnable finishListener) {
|
||||
long maxDelay = 0;
|
||||
ViewPropertyAnimator maxDelayAnimator = null;
|
||||
for (int row = 0; row < views.length; row++) {
|
||||
View[] columns = views[row];
|
||||
for (int col = 0; col < columns.length; col++) {
|
||||
long delay = calculateDelay(row, col);
|
||||
ViewPropertyAnimator animator = startAppearAnimation(columns[col], delay);
|
||||
if (animator != null && delay > maxDelay) {
|
||||
maxDelay = delay;
|
||||
maxDelayAnimator = animator;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (maxDelayAnimator != null) {
|
||||
maxDelayAnimator.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
finishListener.run();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
finishListener.run();
|
||||
}
|
||||
}
|
||||
|
||||
private ViewPropertyAnimator startAppearAnimation(View view, long delay) {
|
||||
if (view == null) return null;
|
||||
view.setAlpha(0f);
|
||||
view.setTranslationY(mStartTranslation);
|
||||
view.animate()
|
||||
.alpha(1f)
|
||||
.translationY(0)
|
||||
.setInterpolator(mLinearOutSlowIn)
|
||||
.setDuration(APPEAR_DURATION)
|
||||
.setStartDelay(delay)
|
||||
.setListener(null);
|
||||
if (view.hasOverlappingRendering()) {
|
||||
view.animate().withLayer();
|
||||
}
|
||||
return view.animate();
|
||||
}
|
||||
|
||||
private long calculateDelay(int row, int col) {
|
||||
return (long) (row * 40 + col * (Math.pow(row, 0.4) + 0.4) * 20);
|
||||
}
|
||||
|
||||
public TimeInterpolator getInterpolator() {
|
||||
return mLinearOutSlowIn;
|
||||
}
|
||||
|
||||
public float getStartTranslation() {
|
||||
return mStartTranslation;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import android.text.TextWatcher;
|
||||
import android.text.method.DigitsKeyListener;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
|
||||
/**
|
||||
@@ -30,12 +31,21 @@ import android.widget.TextView.OnEditorActionListener;
|
||||
public class KeyguardPINView extends KeyguardAbsKeyInputView
|
||||
implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
|
||||
|
||||
private final AppearAnimationUtils mAppearAnimationUtils;
|
||||
private ViewGroup mKeyguardBouncerFrame;
|
||||
private ViewGroup mRow0;
|
||||
private ViewGroup mRow1;
|
||||
private ViewGroup mRow2;
|
||||
private ViewGroup mRow3;
|
||||
private View mDivider;
|
||||
|
||||
public KeyguardPINView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public KeyguardPINView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mAppearAnimationUtils = new AppearAnimationUtils(context);
|
||||
}
|
||||
|
||||
protected void resetState() {
|
||||
@@ -56,6 +66,12 @@ public class KeyguardPINView extends KeyguardAbsKeyInputView
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
||||
mKeyguardBouncerFrame = (ViewGroup) findViewById(R.id.keyguard_bouncer_frame);
|
||||
mRow0 = (ViewGroup) findViewById(R.id.row0);
|
||||
mRow1 = (ViewGroup) findViewById(R.id.row1);
|
||||
mRow2 = (ViewGroup) findViewById(R.id.row2);
|
||||
mRow3 = (ViewGroup) findViewById(R.id.row3);
|
||||
mDivider = findViewById(R.id.divider);
|
||||
final View ok = findViewById(R.id.key_enter);
|
||||
if (ok != null) {
|
||||
ok.setOnClickListener(new View.OnClickListener() {
|
||||
@@ -117,8 +133,45 @@ public class KeyguardPINView extends KeyguardAbsKeyInputView
|
||||
|
||||
@Override
|
||||
public void startAppearAnimation() {
|
||||
// TODO: Fancy animation.
|
||||
setAlpha(0);
|
||||
animate().alpha(1).withLayer().setDuration(200);
|
||||
enableClipping(false);
|
||||
setTranslationY(mAppearAnimationUtils.getStartTranslation());
|
||||
animate()
|
||||
.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
|
||||
}},
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
enableClipping(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void enableClipping(boolean enable) {
|
||||
mKeyguardBouncerFrame.setClipToPadding(enable);
|
||||
mKeyguardBouncerFrame.setClipChildren(enable);
|
||||
mRow1.setClipToPadding(enable);
|
||||
mRow2.setClipToPadding(enable);
|
||||
mRow3.setClipToPadding(enable);
|
||||
setClipChildren(enable);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user