Made it easier to use updatable Animators
The existing system is extended such that AnimationProperties can be easier animated and running animations updated. As a first sample this animates the scale of the icons in the shelf. Change-Id: Ic88e8094d53f37ab13f5e9e00796b63d229a5114 Test: runtest systemui Bug: 32437839
This commit is contained in:
@@ -20,12 +20,16 @@
|
||||
<item type="id" name="translation_y_animator_tag"/>
|
||||
<item type="id" name="translation_z_animator_tag"/>
|
||||
<item type="id" name="alpha_animator_tag"/>
|
||||
<item type="id" name="scale_x_animator_tag"/>
|
||||
<item type="id" name="scale_y_animator_tag"/>
|
||||
<item type="id" name="top_inset_animator_tag"/>
|
||||
<item type="id" name="height_animator_tag"/>
|
||||
<item type="id" name="shadow_alpha_animator_tag"/>
|
||||
<item type="id" name="translation_x_animator_end_value_tag"/>
|
||||
<item type="id" name="translation_y_animator_end_value_tag"/>
|
||||
<item type="id" name="translation_z_animator_end_value_tag"/>
|
||||
<item type="id" name="scale_x_animator_end_value_tag"/>
|
||||
<item type="id" name="scale_y_animator_end_value_tag"/>
|
||||
<item type="id" name="alpha_animator_end_value_tag"/>
|
||||
<item type="id" name="top_inset_animator_end_value_tag"/>
|
||||
<item type="id" name="height_animator_end_value_tag"/>
|
||||
@@ -33,6 +37,8 @@
|
||||
<item type="id" name="translation_x_animator_start_value_tag"/>
|
||||
<item type="id" name="translation_y_animator_start_value_tag"/>
|
||||
<item type="id" name="translation_z_animator_start_value_tag"/>
|
||||
<item type="id" name="scale_x_animator_start_value_tag"/>
|
||||
<item type="id" name="scale_y_animator_start_value_tag"/>
|
||||
<item type="id" name="alpha_animator_start_value_tag"/>
|
||||
<item type="id" name="top_inset_animator_start_value_tag"/>
|
||||
<item type="id" name="height_animator_start_value_tag"/>
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.systemui.statusbar.notification;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.util.Property;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.statusbar.stack.AnimationFilter;
|
||||
import com.android.systemui.statusbar.stack.AnimationProperties;
|
||||
import com.android.systemui.statusbar.stack.ViewState;
|
||||
|
||||
/**
|
||||
* An animator to animate properties
|
||||
*/
|
||||
public class PropertyAnimator {
|
||||
|
||||
public static <T extends View> void startAnimation(final T view,
|
||||
AnimatableProperty animatableProperty, float newEndValue,
|
||||
AnimationProperties properties) {
|
||||
Property<T, Float> property = animatableProperty.getProperty();
|
||||
int animationStartTag = animatableProperty.getAnimationStartTag();
|
||||
int animationEndTag = animatableProperty.getAnimationEndTag();
|
||||
Float previousStartValue = ViewState.getChildTag(view, animationStartTag);
|
||||
Float previousEndValue = ViewState.getChildTag(view, animationEndTag);
|
||||
if (previousEndValue != null && previousEndValue == newEndValue) {
|
||||
return;
|
||||
}
|
||||
int animatorTag = animatableProperty.getAnimatorTag();
|
||||
ValueAnimator previousAnimator = ViewState.getChildTag(view, animatorTag);
|
||||
AnimationFilter filter = properties.getAnimationFilter();
|
||||
if (!filter.shouldAnimateProperty(property)) {
|
||||
// just a local update was performed
|
||||
if (previousAnimator != null) {
|
||||
// we need to increase all animation keyframes of the previous animator by the
|
||||
// relative change to the end value
|
||||
PropertyValuesHolder[] values = previousAnimator.getValues();
|
||||
float relativeDiff = newEndValue - previousEndValue;
|
||||
float newStartValue = previousStartValue + relativeDiff;
|
||||
values[0].setFloatValues(newStartValue, newEndValue);
|
||||
view.setTag(animationStartTag, newStartValue);
|
||||
view.setTag(animationEndTag, newEndValue);
|
||||
previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
|
||||
return;
|
||||
} else {
|
||||
// no new animation needed, let's just apply the value
|
||||
property.set(view, newEndValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Float currentValue = property.get(view);
|
||||
ValueAnimator animator = ValueAnimator.ofFloat(currentValue, newEndValue);
|
||||
animator.addUpdateListener(
|
||||
animation -> property.set(view, (Float) animation.getAnimatedValue()));
|
||||
Interpolator customInterpolator = properties.getCustomInterpolator(view, property);
|
||||
Interpolator interpolator = customInterpolator != null ? customInterpolator
|
||||
: Interpolators.FAST_OUT_SLOW_IN;
|
||||
animator.setInterpolator(interpolator);
|
||||
long newDuration = ViewState.cancelAnimatorAndGetNewDuration(properties.duration,
|
||||
previousAnimator);
|
||||
animator.setDuration(newDuration);
|
||||
if (properties.delay > 0 && (previousAnimator == null
|
||||
|| previousAnimator.getAnimatedFraction() == 0)) {
|
||||
animator.setStartDelay(properties.delay);
|
||||
}
|
||||
AnimatorListenerAdapter listener = properties.getAnimationFinishListener();
|
||||
if (listener != null) {
|
||||
animator.addListener(listener);
|
||||
}
|
||||
// remove the tag when the animation is finished
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
view.setTag(animatorTag, null);
|
||||
view.setTag(animationStartTag, null);
|
||||
view.setTag(animationEndTag, null);
|
||||
}
|
||||
});
|
||||
ViewState.startAnimator(animator, listener);
|
||||
view.setTag(animatorTag, animator);
|
||||
view.setTag(animationStartTag, currentValue);
|
||||
view.setTag(animationEndTag, newEndValue);
|
||||
}
|
||||
|
||||
public interface AnimatableProperty {
|
||||
int getAnimationStartTag();
|
||||
int getAnimationEndTag();
|
||||
int getAnimatorTag();
|
||||
Property getProperty();
|
||||
}
|
||||
}
|
||||
@@ -62,8 +62,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
|
||||
}.setDuration(200);
|
||||
|
||||
private static final AnimationProperties ICON_ANIMATION_PROPERTIES = new AnimationProperties() {
|
||||
private AnimationFilter mAnimationFilter = new AnimationFilter().animateY().animateAlpha();
|
||||
// TODO: add scale
|
||||
private AnimationFilter mAnimationFilter = new AnimationFilter().animateY().animateAlpha()
|
||||
.animateScale();
|
||||
|
||||
@Override
|
||||
public AnimationFilter getAnimationFilter() {
|
||||
@@ -75,13 +75,12 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
|
||||
|
||||
private static final AnimationProperties mTempProperties = new AnimationProperties() {
|
||||
private AnimationFilter mAnimationFilter = new AnimationFilter();
|
||||
// TODO: add scale
|
||||
|
||||
@Override
|
||||
public AnimationFilter getAnimationFilter() {
|
||||
return mAnimationFilter;
|
||||
}
|
||||
}.setDuration(CANNED_ANIMATION_DURATION);
|
||||
};
|
||||
|
||||
private static final AnimationProperties ADD_ICON_PROPERTIES = new AnimationProperties() {
|
||||
private AnimationFilter mAnimationFilter = new AnimationFilter().animateAlpha();
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
|
||||
package com.android.systemui.statusbar.stack;
|
||||
|
||||
import android.support.v4.util.ArraySet;
|
||||
import android.util.Property;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Filters the animations for only a certain type of properties.
|
||||
@@ -37,12 +42,19 @@ public class AnimationFilter {
|
||||
boolean hasDarkEvent;
|
||||
boolean hasHeadsUpDisappearClickEvent;
|
||||
int darkAnimationOriginIndex;
|
||||
private ArraySet<Property> mAnimatedProperties = new ArraySet<>();
|
||||
|
||||
public AnimationFilter animateAlpha() {
|
||||
animateAlpha = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AnimationFilter animateScale() {
|
||||
animate(View.SCALE_X);
|
||||
animate(View.SCALE_Y);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AnimationFilter animateX() {
|
||||
animateX = true;
|
||||
return this;
|
||||
@@ -132,6 +144,7 @@ public class AnimationFilter {
|
||||
animateHideSensitive |= filter.animateHideSensitive;
|
||||
animateShadowAlpha |= filter.animateShadowAlpha;
|
||||
hasDelays |= filter.hasDelays;
|
||||
mAnimatedProperties.addAll(filter.mAnimatedProperties);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
@@ -151,5 +164,16 @@ public class AnimationFilter {
|
||||
hasHeadsUpDisappearClickEvent = false;
|
||||
darkAnimationOriginIndex =
|
||||
NotificationStackScrollLayout.AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE;
|
||||
mAnimatedProperties.clear();
|
||||
}
|
||||
|
||||
public AnimationFilter animate(Property property) {
|
||||
mAnimatedProperties.add(property);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean shouldAnimateProperty(Property property) {
|
||||
// TODO: migrate all existing animators to properties
|
||||
return mAnimatedProperties.contains(property);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,14 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.util.Property;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.ExpandableView;
|
||||
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
||||
import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||
|
||||
/**
|
||||
@@ -60,6 +62,54 @@ public class ViewState {
|
||||
private static final int TAG_START_TRANSLATION_Z = R.id.translation_z_animator_start_value_tag;
|
||||
private static final int TAG_START_ALPHA = R.id.alpha_animator_start_value_tag;
|
||||
|
||||
private static final PropertyAnimator.AnimatableProperty SCALE_X_PROPERTY
|
||||
= new PropertyAnimator.AnimatableProperty() {
|
||||
|
||||
@Override
|
||||
public int getAnimationStartTag() {
|
||||
return R.id.scale_x_animator_start_value_tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAnimationEndTag() {
|
||||
return R.id.scale_x_animator_end_value_tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAnimatorTag() {
|
||||
return R.id.scale_x_animator_tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Property getProperty() {
|
||||
return View.SCALE_X;
|
||||
}
|
||||
};
|
||||
|
||||
private static final PropertyAnimator.AnimatableProperty SCALE_Y_PROPERTY
|
||||
= new PropertyAnimator.AnimatableProperty() {
|
||||
|
||||
@Override
|
||||
public int getAnimationStartTag() {
|
||||
return R.id.scale_y_animator_start_value_tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAnimationEndTag() {
|
||||
return R.id.scale_y_animator_end_value_tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAnimatorTag() {
|
||||
return R.id.scale_y_animator_tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Property getProperty() {
|
||||
return View.SCALE_Y;
|
||||
}
|
||||
};
|
||||
|
||||
public float alpha;
|
||||
public float xTranslation;
|
||||
public float yTranslation;
|
||||
@@ -125,13 +175,19 @@ public class ViewState {
|
||||
}
|
||||
|
||||
// apply scaleX
|
||||
if (view.getScaleX() != this.scaleX) {
|
||||
view.setScaleX(this.scaleX);
|
||||
boolean animatingScaleX = isAnimating(view, SCALE_X_PROPERTY);
|
||||
if (animatingScaleX) {
|
||||
updateAnimation(view, SCALE_X_PROPERTY, scaleX);
|
||||
} else if (view.getScaleX() != scaleX) {
|
||||
view.setScaleX(scaleX);
|
||||
}
|
||||
|
||||
// apply scaleY
|
||||
if (view.getScaleY() != this.scaleY) {
|
||||
view.setScaleY(this.scaleY);
|
||||
boolean animatingScaleY = isAnimating(view, SCALE_Y_PROPERTY);
|
||||
if (animatingScaleY) {
|
||||
updateAnimation(view, SCALE_Y_PROPERTY, scaleY);
|
||||
} else if (view.getScaleY() != scaleY) {
|
||||
view.setScaleY(scaleY);
|
||||
}
|
||||
|
||||
boolean becomesInvisible = this.alpha == 0.0f || (this.hidden && !isAnimating(view));
|
||||
@@ -179,13 +235,23 @@ public class ViewState {
|
||||
if (isAnimating(view, TAG_ANIMATOR_ALPHA)) {
|
||||
return true;
|
||||
}
|
||||
if (isAnimating(view, SCALE_X_PROPERTY)) {
|
||||
return true;
|
||||
}
|
||||
if (isAnimating(view, SCALE_Y_PROPERTY)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isAnimating(View view, int tag) {
|
||||
private static boolean isAnimating(View view, int tag) {
|
||||
return getChildTag(view, tag) != null;
|
||||
}
|
||||
|
||||
public static boolean isAnimating(View view, PropertyAnimator.AnimatableProperty property) {
|
||||
return getChildTag(view, property.getAnimatorTag()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start an animation to this viewstate
|
||||
* @param child the view to animate
|
||||
@@ -226,6 +292,20 @@ public class ViewState {
|
||||
abortAnimation(child, TAG_ANIMATOR_TRANSLATION_Z);
|
||||
}
|
||||
|
||||
// start scaleX animation
|
||||
if (child.getScaleX() != scaleX) {
|
||||
PropertyAnimator.startAnimation(child, SCALE_X_PROPERTY, scaleX, animationProperties);
|
||||
} else {
|
||||
abortAnimation(child, SCALE_X_PROPERTY.getAnimatorTag());
|
||||
}
|
||||
|
||||
// start scaleX animation
|
||||
if (child.getScaleY() != scaleY) {
|
||||
PropertyAnimator.startAnimation(child, SCALE_Y_PROPERTY, scaleY, animationProperties);
|
||||
} else {
|
||||
abortAnimation(child, SCALE_Y_PROPERTY.getAnimatorTag());
|
||||
}
|
||||
|
||||
// start alpha animation
|
||||
if (alphaChanging) {
|
||||
startAlphaAnimation(child, animationProperties);
|
||||
@@ -320,6 +400,11 @@ public class ViewState {
|
||||
startZTranslationAnimation(view, NO_NEW_ANIMATIONS);
|
||||
}
|
||||
|
||||
private void updateAnimation(View view, PropertyAnimator.AnimatableProperty property,
|
||||
float endValue) {
|
||||
PropertyAnimator.startAnimation(view, property, endValue, NO_NEW_ANIMATIONS);
|
||||
}
|
||||
|
||||
private void startZTranslationAnimation(final View child, AnimationProperties properties) {
|
||||
Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_Z);
|
||||
Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Z);
|
||||
@@ -514,7 +599,7 @@ public class ViewState {
|
||||
}
|
||||
}
|
||||
|
||||
protected void startAnimator(Animator animator, AnimatorListenerAdapter listener) {
|
||||
public static void startAnimator(Animator animator, AnimatorListenerAdapter listener) {
|
||||
if (listener != null) {
|
||||
// Even if there's a delay we'd want to notify it of the start immediately.
|
||||
listener.onAnimationStart(animator);
|
||||
@@ -540,7 +625,8 @@ public class ViewState {
|
||||
* @param previousAnimator the animator which was running before
|
||||
* @return the new duration
|
||||
*/
|
||||
protected long cancelAnimatorAndGetNewDuration(long duration, ValueAnimator previousAnimator) {
|
||||
public static long cancelAnimatorAndGetNewDuration(long duration,
|
||||
ValueAnimator previousAnimator) {
|
||||
long newDuration = duration;
|
||||
if (previousAnimator != null) {
|
||||
// We take either the desired length of the new animation or the remaining time of
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.systemui.notification;
|
||||
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.support.test.annotation.UiThreadTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
|
||||
import android.util.FloatProperty;
|
||||
import android.util.Property;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
||||
import com.android.systemui.statusbar.stack.AnimationFilter;
|
||||
import com.android.systemui.statusbar.stack.AnimationProperties;
|
||||
import com.android.systemui.statusbar.stack.ViewState;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class PropertyAnimatorTest extends SysuiTestCase {
|
||||
|
||||
private View mView;
|
||||
private FloatProperty<View> mEffectiveProperty = new FloatProperty<View>("TEST") {
|
||||
public float mValue = 100;
|
||||
|
||||
@Override
|
||||
public void setValue(View view, float value) {
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(View object) {
|
||||
return mValue;
|
||||
}
|
||||
};
|
||||
private PropertyAnimator.AnimatableProperty mProperty
|
||||
= new PropertyAnimator.AnimatableProperty() {
|
||||
|
||||
@Override
|
||||
public int getAnimationStartTag() {
|
||||
return R.id.scale_x_animator_start_value_tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAnimationEndTag() {
|
||||
return R.id.scale_x_animator_end_value_tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAnimatorTag() {
|
||||
return R.id.scale_x_animator_tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Property getProperty() {
|
||||
return mEffectiveProperty;
|
||||
}
|
||||
};
|
||||
private AnimatorListenerAdapter mFinishListener = mock(AnimatorListenerAdapter.class);
|
||||
private AnimationProperties mAnimationProperties = new AnimationProperties() {
|
||||
@Override
|
||||
public AnimationFilter getAnimationFilter() {
|
||||
return mAnimationFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnimatorListenerAdapter getAnimationFinishListener() {
|
||||
return mFinishListener;
|
||||
}
|
||||
}.setDuration(200);
|
||||
private AnimationFilter mAnimationFilter = new AnimationFilter();
|
||||
private Interpolator mTestInterpolator = Interpolators.ALPHA_IN;
|
||||
|
||||
|
||||
@Before
|
||||
@UiThreadTest
|
||||
public void setUp() {
|
||||
mView = new View(getContext());
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testAnimationStarted() {
|
||||
mAnimationFilter.reset();
|
||||
mAnimationFilter.animate(mProperty.getProperty());
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200, mAnimationProperties);
|
||||
assertTrue(ViewState.isAnimating(mView, mProperty));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testNoAnimationStarted() {
|
||||
mAnimationFilter.reset();
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200, mAnimationProperties);
|
||||
assertFalse(ViewState.isAnimating(mView, mProperty));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testEndValueUpdated() {
|
||||
mAnimationFilter.reset();
|
||||
mAnimationFilter.animate(mProperty.getProperty());
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
|
||||
assertEquals(ViewState.getChildTag(mView, mProperty.getAnimationEndTag()),
|
||||
Float.valueOf(200f));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testStartTagUpdated() {
|
||||
mEffectiveProperty.set(mView, 100f);
|
||||
mAnimationFilter.reset();
|
||||
mAnimationFilter.animate(mProperty.getProperty());
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
|
||||
assertEquals(ViewState.getChildTag(mView, mProperty.getAnimationStartTag()),
|
||||
Float.valueOf(100f));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testValueIsSetUnAnimated() {
|
||||
mAnimationFilter.reset();
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
|
||||
assertEquals(Float.valueOf(200f), mEffectiveProperty.get(mView));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testAnimationToRightValueUpdated() {
|
||||
mAnimationFilter.reset();
|
||||
mAnimationFilter.animate(mProperty.getProperty());
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
|
||||
mAnimationFilter.reset();
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 220f, mAnimationProperties);
|
||||
assertTrue(ViewState.isAnimating(mView, mProperty));
|
||||
assertEquals(ViewState.getChildTag(mView, mProperty.getAnimationEndTag()),
|
||||
Float.valueOf(220f));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testAnimationToRightValueUpdateAnimated() {
|
||||
mAnimationFilter.reset();
|
||||
mAnimationFilter.animate(mProperty.getProperty());
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
|
||||
mAnimationFilter.reset();
|
||||
mAnimationFilter.animate(mProperty.getProperty());
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 220f, mAnimationProperties);
|
||||
assertTrue(ViewState.isAnimating(mView, mProperty));
|
||||
assertEquals(ViewState.getChildTag(mView, mProperty.getAnimationEndTag()),
|
||||
Float.valueOf(220f));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testStartTagShiftedWhenChanging() {
|
||||
mEffectiveProperty.set(mView, 100f);
|
||||
mAnimationFilter.reset();
|
||||
mAnimationFilter.animate(mProperty.getProperty());
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
|
||||
mAnimationFilter.reset();
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 220f, mAnimationProperties);
|
||||
assertEquals(ViewState.getChildTag(mView, mProperty.getAnimationStartTag()),
|
||||
Float.valueOf(120f));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testUsingDuration() {
|
||||
mAnimationFilter.reset();
|
||||
mAnimationFilter.animate(mProperty.getProperty());
|
||||
mAnimationProperties.setDuration(500);
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
|
||||
ValueAnimator animator = ViewState.getChildTag(mView, mProperty.getAnimatorTag());
|
||||
assertNotNull(animator);
|
||||
assertEquals(animator.getDuration(), 500);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testUsingDelay() {
|
||||
mAnimationFilter.reset();
|
||||
mAnimationFilter.animate(mProperty.getProperty());
|
||||
mAnimationProperties.setDelay(200);
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
|
||||
ValueAnimator animator = ViewState.getChildTag(mView, mProperty.getAnimatorTag());
|
||||
assertNotNull(animator);
|
||||
assertEquals(animator.getStartDelay(), 200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testUsingInterpolator() {
|
||||
mAnimationFilter.reset();
|
||||
mAnimationFilter.animate(mProperty.getProperty());
|
||||
mAnimationProperties.setCustomInterpolator(mEffectiveProperty, mTestInterpolator);
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
|
||||
ValueAnimator animator = ViewState.getChildTag(mView, mProperty.getAnimatorTag());
|
||||
assertNotNull(animator);
|
||||
assertEquals(animator.getInterpolator(), mTestInterpolator);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testUsingListener() {
|
||||
mAnimationFilter.reset();
|
||||
mAnimationFilter.animate(mProperty.getProperty());
|
||||
mAnimationProperties.setCustomInterpolator(mEffectiveProperty, mTestInterpolator);
|
||||
PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
|
||||
ValueAnimator animator = ViewState.getChildTag(mView, mProperty.getAnimatorTag());
|
||||
assertNotNull(animator);
|
||||
assertTrue(animator.getListeners().contains(mFinishListener));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user