diff options
| -rw-r--r-- | core/java/android/view/animation/AnimationUtils.java | 2 | ||||
| -rw-r--r-- | core/java/android/view/animation/ClipRectAnimation.java | 111 | ||||
| -rw-r--r-- | core/res/res/anim/activity_close_enter.xml | 18 | ||||
| -rw-r--r-- | core/res/res/anim/activity_close_exit.xml | 34 | ||||
| -rw-r--r-- | core/res/res/anim/activity_open_enter.xml | 31 | ||||
| -rw-r--r-- | core/res/res/anim/activity_open_exit.xml | 19 | ||||
| -rw-r--r-- | core/res/res/interpolator/activity_close_dim.xml | 22 | ||||
| -rw-r--r-- | core/res/res/values/attrs.xml | 11 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java | 15 |
9 files changed, 217 insertions, 46 deletions
diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java index f5c36139df0f..990fbdb019d6 100644 --- a/core/java/android/view/animation/AnimationUtils.java +++ b/core/java/android/view/animation/AnimationUtils.java @@ -156,6 +156,8 @@ public class AnimationUtils { anim = new RotateAnimation(c, attrs); } else if (name.equals("translate")) { anim = new TranslateAnimation(c, attrs); + } else if (name.equals("cliprect")) { + anim = new ClipRectAnimation(c, attrs); } else { throw new RuntimeException("Unknown animation name: " + parser.getName()); } diff --git a/core/java/android/view/animation/ClipRectAnimation.java b/core/java/android/view/animation/ClipRectAnimation.java index e194927e8301..21509d3a1159 100644 --- a/core/java/android/view/animation/ClipRectAnimation.java +++ b/core/java/android/view/animation/ClipRectAnimation.java @@ -16,7 +16,11 @@ package android.view.animation; +import android.content.Context; +import android.content.res.TypedArray; import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.DisplayMetrics; /** * An animation that controls the clip of an object. See the @@ -26,8 +30,84 @@ import android.graphics.Rect; * @hide */ public class ClipRectAnimation extends Animation { - protected Rect mFromRect = new Rect(); - protected Rect mToRect = new Rect(); + protected final Rect mFromRect = new Rect(); + protected final Rect mToRect = new Rect(); + + private int mFromLeftType = ABSOLUTE; + private int mFromTopType = ABSOLUTE; + private int mFromRightType = ABSOLUTE; + private int mFromBottomType = ABSOLUTE; + + private int mToLeftType = ABSOLUTE; + private int mToTopType = ABSOLUTE; + private int mToRightType = ABSOLUTE; + private int mToBottomType = ABSOLUTE; + + private float mFromLeftValue; + private float mFromTopValue; + private float mFromRightValue; + private float mFromBottomValue; + + private float mToLeftValue; + private float mToTopValue; + private float mToRightValue; + private float mToBottomValue; + + /** + * Constructor used when a ClipRectAnimation is loaded from a resource. + * + * @param context Application context to use + * @param attrs Attribute set from which to read values + */ + public ClipRectAnimation(Context context, AttributeSet attrs) { + super(context, attrs); + + TypedArray a = context.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.ClipRectAnimation); + + Description d = Description.parseValue(a.peekValue( + com.android.internal.R.styleable.ClipRectAnimation_fromLeft)); + mFromLeftType = d.type; + mFromLeftValue = d.value; + + d = Description.parseValue(a.peekValue( + com.android.internal.R.styleable.ClipRectAnimation_fromTop)); + mFromTopType = d.type; + mFromTopValue = d.value; + + d = Description.parseValue(a.peekValue( + com.android.internal.R.styleable.ClipRectAnimation_fromRight)); + mFromRightType = d.type; + mFromRightValue = d.value; + + d = Description.parseValue(a.peekValue( + com.android.internal.R.styleable.ClipRectAnimation_fromBottom)); + mFromBottomType = d.type; + mFromBottomValue = d.value; + + + d = Description.parseValue(a.peekValue( + com.android.internal.R.styleable.ClipRectAnimation_toLeft)); + mToLeftType = d.type; + mToLeftValue = d.value; + + d = Description.parseValue(a.peekValue( + com.android.internal.R.styleable.ClipRectAnimation_toTop)); + mToTopType = d.type; + mToTopValue = d.value; + + d = Description.parseValue(a.peekValue( + com.android.internal.R.styleable.ClipRectAnimation_toRight)); + mToRightType = d.type; + mToRightValue = d.value; + + d = Description.parseValue(a.peekValue( + com.android.internal.R.styleable.ClipRectAnimation_toBottom)); + mToBottomType = d.type; + mToBottomValue = d.value; + + a.recycle(); + } /** * Constructor to use when building a ClipRectAnimation from code @@ -39,8 +119,15 @@ public class ClipRectAnimation extends Animation { if (fromClip == null || toClip == null) { throw new RuntimeException("Expected non-null animation clip rects"); } - mFromRect.set(fromClip); - mToRect.set(toClip); + mFromLeftValue = fromClip.left; + mFromTopValue = fromClip.top; + mFromRightValue= fromClip.right; + mFromBottomValue = fromClip.bottom; + + mToLeftValue = toClip.left; + mToTopValue = toClip.top; + mToRightValue= toClip.right; + mToBottomValue = toClip.bottom; } /** @@ -48,8 +135,7 @@ public class ClipRectAnimation extends Animation { */ public ClipRectAnimation(int fromL, int fromT, int fromR, int fromB, int toL, int toT, int toR, int toB) { - mFromRect.set(fromL, fromT, fromR, fromB); - mToRect.set(toL, toT, toR, toB); + this(new Rect(fromL, fromT, fromR, fromB), new Rect(toL, toT, toR, toB)); } @Override @@ -65,4 +151,17 @@ public class ClipRectAnimation extends Animation { public boolean willChangeTransformationMatrix() { return false; } + + @Override + public void initialize(int width, int height, int parentWidth, int parentHeight) { + super.initialize(width, height, parentWidth, parentHeight); + mFromRect.set((int) resolveSize(mFromLeftType, mFromLeftValue, width, parentWidth), + (int) resolveSize(mFromTopType, mFromTopValue, height, parentHeight), + (int) resolveSize(mFromRightType, mFromRightValue, width, parentWidth), + (int) resolveSize(mFromBottomType, mFromBottomValue, height, parentHeight)); + mToRect.set((int) resolveSize(mToLeftType, mToLeftValue, width, parentWidth), + (int) resolveSize(mToTopType, mToTopValue, height, parentHeight), + (int) resolveSize(mToRightType, mToRightValue, width, parentWidth), + (int) resolveSize(mToBottomType, mToBottomValue, height, parentHeight)); + } } diff --git a/core/res/res/anim/activity_close_enter.xml b/core/res/res/anim/activity_close_enter.xml index a67b0ca38519..371bcfef7ec9 100644 --- a/core/res/res/anim/activity_close_enter.xml +++ b/core/res/res/anim/activity_close_enter.xml @@ -17,9 +17,17 @@ */ --> -<set xmlns:android="http://schemas.android.com/apk/res/android" android:zAdjustment="normal"> - <alpha android:fromAlpha="0.7" android:toAlpha="1.0" - android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/linear_out_slow_in" - android:duration="250"/> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:shareInterpolator="false"> + <translate + android:fromYDelta="-2%" + android:toYDelta="0" + android:interpolator="@interpolator/fast_out_slow_in" + android:duration="425"/> + <alpha + android:fromAlpha="0.9" + android:toAlpha="1.0" + android:interpolator="@interpolator/activity_close_dim" + android:startOffset="0" + android:duration="425"/> </set>
\ No newline at end of file diff --git a/core/res/res/anim/activity_close_exit.xml b/core/res/res/anim/activity_close_exit.xml index d8c42ed808f1..143bedb985e1 100644 --- a/core/res/res/anim/activity_close_exit.xml +++ b/core/res/res/anim/activity_close_exit.xml @@ -18,15 +18,27 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" android:zAdjustment="top"> - <alpha android:fromAlpha="1.0" android:toAlpha="0.0" - android:interpolator="@interpolator/linear" - android:fillEnabled="true" - android:fillBefore="false" android:fillAfter="true" - android:startOffset="100" - android:duration="150"/> - <translate android:fromYDelta="0%" android:toYDelta="8%" - android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/accelerate_quart" - android:duration="250"/> + android:shareInterpolator="false" + android:zAdjustment="top"> + <translate + android:fromYDelta="0" + android:toYDelta="4.1%" + android:interpolator="@interpolator/fast_out_slow_in" + android:duration="425"/> + <cliprect + android:fromLeft="0%" + android:fromTop="0%" + android:fromRight="100%" + android:fromBottom="100%" + android:toLeft="0%" + android:toTop="95.9%" + android:toRight="100%" + android:toBottom="100%" + android:interpolator="@interpolator/exaggerated_ease" + android:duration="425"/> + <alpha + android:fromAlpha="1.0" + android:toAlpha="1.0" + android:interpolator="@interpolator/fast_out_linear_in" + android:duration="425"/> </set>
\ No newline at end of file diff --git a/core/res/res/anim/activity_open_enter.xml b/core/res/res/anim/activity_open_enter.xml index 1d949d2f7446..f9381b458c20 100644 --- a/core/res/res/anim/activity_open_enter.xml +++ b/core/res/res/anim/activity_open_enter.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- /* ** Copyright 2009, The Android Open Source Project ** @@ -18,15 +17,21 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" - android:zAdjustment="top"> - <alpha android:fromAlpha="0.0" android:toAlpha="1.0" - android:interpolator="@interpolator/decelerate_quart" - android:fillEnabled="true" - android:fillBefore="false" android:fillAfter="true" - android:duration="200"/> - <translate android:fromYDelta="8%" android:toYDelta="0" - android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/decelerate_quint" - android:duration="350"/> + android:shareInterpolator="false"> + <translate + android:fromYDelta="4.1%" + android:toYDelta="0" + android:interpolator="@interpolator/fast_out_slow_in" + android:duration="425"/> + <cliprect + android:fromLeft="0%" + android:fromTop="95.9%" + android:fromRight="100%" + android:fromBottom="100%" + android:toLeft="0%" + android:toTop="0%" + android:toRight="100%" + android:toBottom="100%" + android:interpolator="@interpolator/exaggerated_ease" + android:duration="425"/> </set>
\ No newline at end of file diff --git a/core/res/res/anim/activity_open_exit.xml b/core/res/res/anim/activity_open_exit.xml index 3a84197f8f63..d52b150391fb 100644 --- a/core/res/res/anim/activity_open_exit.xml +++ b/core/res/res/anim/activity_open_exit.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- /* ** Copyright 2009, The Android Open Source Project ** @@ -18,9 +17,15 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:background="#ff000000" android:zAdjustment="normal"> - <alpha android:fromAlpha="1.0" android:toAlpha="0.7" - android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="217"/> + android:shareInterpolator="false"> + <translate + android:fromYDelta="0" + android:toYDelta="-2%" + android:interpolator="@interpolator/fast_out_slow_in" + android:duration="425"/> + <alpha + android:fromAlpha="1.0" + android:toAlpha="0.9" + android:interpolator="@interpolator/linear" + android:duration="117"/> </set>
\ No newline at end of file diff --git a/core/res/res/interpolator/activity_close_dim.xml b/core/res/res/interpolator/activity_close_dim.xml new file mode 100644 index 000000000000..faad1399ff49 --- /dev/null +++ b/core/res/res/interpolator/activity_close_dim.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2018 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 + --> + +<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" + android:controlX1="0.33" + android:controlY1="0" + android:controlX2="1" + android:controlY2="1"/> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 4eaf93d822b2..ffe68dc4195b 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -6336,6 +6336,17 @@ <attr name="toAlpha" format="float" /> </declare-styleable> + <declare-styleable name="ClipRectAnimation"> + <attr name="fromLeft" format="fraction" /> + <attr name="fromTop" format="fraction" /> + <attr name="fromRight" format="fraction" /> + <attr name="fromBottom" format="fraction" /> + <attr name="toLeft" format="fraction" /> + <attr name="toTop" format="fraction" /> + <attr name="toRight" format="fraction" /> + <attr name="toBottom" format="fraction" /> + </declare-styleable> + <declare-styleable name="LayoutAnimation"> <!-- Fraction of the animation duration used to delay the beginning of the animation of each child. --> diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java index f8db4faaa81f..794d0336904a 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java @@ -54,7 +54,7 @@ public class WindowAnimationSpecTest { @Test public void testApply_clipNone() { Rect windowCrop = new Rect(0, 0, 20, 20); - Animation a = new ClipRectAnimation(windowCrop, windowCrop); + Animation a = createClipRectAnimation(windowCrop, windowCrop); WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null, mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_NONE); windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0); @@ -99,7 +99,8 @@ public class WindowAnimationSpecTest { public void testApply_clipBeforeNoStackBounds() { // Stack bounds is (0, 0, 0, 0) animation clip is (0, 0, 20, 20) Rect windowCrop = new Rect(0, 0, 20, 20); - Animation a = new ClipRectAnimation(windowCrop, windowCrop); + Animation a = createClipRectAnimation(windowCrop, windowCrop); + a.initialize(0, 0, 0, 0); WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null, null, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM); windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0); @@ -110,7 +111,7 @@ public class WindowAnimationSpecTest { public void testApply_clipBeforeSmallerAnimationClip() { // Stack bounds is (0, 0, 10, 10) animation clip is (0, 0, 5, 5) Rect windowCrop = new Rect(0, 0, 5, 5); - Animation a = new ClipRectAnimation(windowCrop, windowCrop); + Animation a = createClipRectAnimation(windowCrop, windowCrop); WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null, mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM); windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0); @@ -122,11 +123,17 @@ public class WindowAnimationSpecTest { public void testApply_clipBeforeSmallerStackClip() { // Stack bounds is (0, 0, 10, 10) animation clip is (0, 0, 20, 20) Rect windowCrop = new Rect(0, 0, 20, 20); - Animation a = new ClipRectAnimation(windowCrop, windowCrop); + Animation a = createClipRectAnimation(windowCrop, windowCrop); WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null, mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM); windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0); verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(rect -> rect.equals(mStackBounds))); } + + private Animation createClipRectAnimation(Rect fromClip, Rect toClip) { + Animation a = new ClipRectAnimation(fromClip, toClip); + a.initialize(0, 0, 0, 0); + return a; + } } |