upload android base code part1
This commit is contained in:
parent
e02f198e2d
commit
0a1de6c4b3
48159 changed files with 9071466 additions and 0 deletions
24
android/frameworks/support/dynamic-animation/tests/AndroidManifest.xml
Executable file
24
android/frameworks/support/dynamic-animation/tests/AndroidManifest.xml
Executable file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2017 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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="android.support.animation.test">
|
||||
<uses-sdk android:targetSdkVersion="${target-sdk-version}"/>
|
||||
|
||||
<application android:supportsRtl="true">
|
||||
<activity android:name="android.support.dynamicanimation.tests.AnimationActivity"/>
|
||||
</application>
|
||||
</manifest>
|
17
android/frameworks/support/dynamic-animation/tests/NO_DOCS
Normal file
17
android/frameworks/support/dynamic-animation/tests/NO_DOCS
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Copyright (C) 2017 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.
|
||||
|
||||
Having this file, named NO_DOCS, in a directory will prevent
|
||||
Android javadocs from being generated for java files under
|
||||
the directory. This is especially useful for test projects.
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2017 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.
|
||||
-->
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<View
|
||||
android:id="@+id/anim_view"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/anim_another_view"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"/>
|
||||
|
||||
</FrameLayout>
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2017 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 android.support.dynamicanimation.tests;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.dynamicanimation.test.R;
|
||||
|
||||
public class AnimationActivity extends Activity {
|
||||
@Override
|
||||
public void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
setContentView(R.layout.anim_layout);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* Copyright (C) 2017 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 android.support.dynamicanimation.tests;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.floatThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.support.animation.DynamicAnimation;
|
||||
import android.support.animation.FlingAnimation;
|
||||
import android.support.animation.FloatPropertyCompat;
|
||||
import android.support.animation.FloatValueHolder;
|
||||
import android.support.dynamicanimation.test.R;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.MediumTest;
|
||||
import android.support.test.rule.ActivityTestRule;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.view.View;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.internal.matchers.GreaterThan;
|
||||
import org.mockito.internal.matchers.LessThan;
|
||||
|
||||
@MediumTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class FlingTests {
|
||||
@Rule
|
||||
public final ActivityTestRule<AnimationActivity> mActivityTestRule;
|
||||
public View mView1;
|
||||
public View mView2;
|
||||
|
||||
@Rule
|
||||
public ExpectedException mExpectedException = ExpectedException.none();
|
||||
|
||||
public FlingTests() {
|
||||
mActivityTestRule = new ActivityTestRule<>(AnimationActivity.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
mView1 = mActivityTestRule.getActivity().findViewById(R.id.anim_view);
|
||||
mView2 = mActivityTestRule.getActivity().findViewById(R.id.anim_another_view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that custom properties are supported.
|
||||
*/
|
||||
@Test
|
||||
public void testCustomProperties() {
|
||||
final Object animObj = new Object();
|
||||
FloatPropertyCompat property = new FloatPropertyCompat("") {
|
||||
private float mValue = 0f;
|
||||
@Override
|
||||
public float getValue(Object object) {
|
||||
assertEquals(animObj, object);
|
||||
return mValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Object object, float value) {
|
||||
assertEquals(animObj, object);
|
||||
assertTrue(value > mValue);
|
||||
assertTrue(value >= 100);
|
||||
mValue = value;
|
||||
}
|
||||
};
|
||||
final FlingAnimation anim = new FlingAnimation(animObj, property);
|
||||
DynamicAnimation.OnAnimationEndListener listener = mock(
|
||||
DynamicAnimation.OnAnimationEndListener.class);
|
||||
anim.addEndListener(listener);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.setStartValue(100).setStartVelocity(2000).start();
|
||||
}
|
||||
});
|
||||
verify(listener, timeout(1000)).onAnimationEnd(eq(anim), eq(false), floatThat(
|
||||
new GreaterThan(110f)), eq(0f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that spring animation can work with a single property without an object.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueHolder() {
|
||||
FloatValueHolder floatValueHolder = new FloatValueHolder();
|
||||
assertEquals(0.0f, floatValueHolder.getValue());
|
||||
|
||||
final FlingAnimation anim = new FlingAnimation(floatValueHolder).setStartVelocity(-2500);
|
||||
|
||||
DynamicAnimation.OnAnimationEndListener listener = mock(
|
||||
DynamicAnimation.OnAnimationEndListener.class);
|
||||
anim.addEndListener(listener);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.start();
|
||||
}
|
||||
});
|
||||
verify(listener, timeout(1000)).onAnimationEnd(eq(anim), eq(false), floatThat(
|
||||
new LessThan(-50f)), eq(0f));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test that friction does affect how fast the slow down happens. Fling animation with
|
||||
* higher friction should finish first.
|
||||
*/
|
||||
@Test
|
||||
public void testFriction() {
|
||||
FloatValueHolder floatValueHolder = new FloatValueHolder();
|
||||
float lowFriction = 0.5f;
|
||||
float highFriction = 2f;
|
||||
final FlingAnimation animLowFriction = new FlingAnimation(floatValueHolder);
|
||||
final FlingAnimation animHighFriction = new FlingAnimation(floatValueHolder);
|
||||
|
||||
animHighFriction.setFriction(highFriction);
|
||||
animLowFriction.setFriction(lowFriction);
|
||||
|
||||
DynamicAnimation.OnAnimationEndListener listener = mock(
|
||||
DynamicAnimation.OnAnimationEndListener.class);
|
||||
animHighFriction.addEndListener(listener);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
animHighFriction.setStartVelocity(5000).setStartValue(0).start();
|
||||
animLowFriction.setStartVelocity(5000).setStartValue(0).start();
|
||||
}
|
||||
});
|
||||
|
||||
verify(listener, timeout(1000)).onAnimationEnd(eq(animHighFriction), eq(false), floatThat(
|
||||
new GreaterThan(200f)), eq(0f));
|
||||
// By the time high scalar animation finishes, the lower friction animation should still be
|
||||
// running.
|
||||
assertTrue(animLowFriction.isRunning());
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
animLowFriction.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(lowFriction, animLowFriction.getFriction(), 0f);
|
||||
assertEquals(highFriction, animHighFriction.getFriction(), 0f);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that velocity threshold does affect how early fling animation ends. An animation with
|
||||
* higher velocity threshold should finish first.
|
||||
*/
|
||||
@Test
|
||||
public void testVelocityThreshold() {
|
||||
FloatValueHolder floatValueHolder = new FloatValueHolder();
|
||||
float lowThreshold = 5f;
|
||||
final float highThreshold = 10f;
|
||||
final FlingAnimation animLowThreshold = new FlingAnimation(floatValueHolder);
|
||||
final FlingAnimation animHighThreshold = new FlingAnimation(floatValueHolder);
|
||||
|
||||
animHighThreshold.setMinimumVisibleChange(highThreshold);
|
||||
animHighThreshold.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(DynamicAnimation animation, float value, float velocity) {
|
||||
if (velocity != 0f) {
|
||||
// Other than last frame, velocity should always be above threshold
|
||||
assertTrue(velocity >= highThreshold);
|
||||
}
|
||||
}
|
||||
});
|
||||
animLowThreshold.setMinimumVisibleChange(lowThreshold);
|
||||
|
||||
DynamicAnimation.OnAnimationEndListener listener = mock(
|
||||
DynamicAnimation.OnAnimationEndListener.class);
|
||||
animHighThreshold.addEndListener(listener);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
animHighThreshold.setStartVelocity(2000).setStartValue(0).start();
|
||||
animLowThreshold.setStartVelocity(2000).setStartValue(0).start();
|
||||
}
|
||||
});
|
||||
|
||||
verify(listener, timeout(1000)).onAnimationEnd(eq(animHighThreshold), eq(false), floatThat(
|
||||
new GreaterThan(200f)), eq(0f));
|
||||
// By the time high scalar animation finishes, the lower friction animation should still be
|
||||
// running.
|
||||
assertTrue(animLowThreshold.isRunning());
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
animLowThreshold.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(lowThreshold, animLowThreshold.getMinimumVisibleChange(), 0f);
|
||||
assertEquals(highThreshold, animHighThreshold.getMinimumVisibleChange(), 0f);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,791 @@
|
|||
/*
|
||||
* Copyright (C) 2017 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 android.support.dynamicanimation.tests;
|
||||
|
||||
import static junit.framework.Assert.fail;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.AdditionalMatchers.lt;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyFloat;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
import static org.mockito.Mockito.atMost;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.support.animation.DynamicAnimation;
|
||||
import android.support.animation.FloatPropertyCompat;
|
||||
import android.support.animation.FloatValueHolder;
|
||||
import android.support.animation.SpringAnimation;
|
||||
import android.support.animation.SpringForce;
|
||||
import android.support.dynamicanimation.test.R;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.LargeTest;
|
||||
import android.support.test.filters.MediumTest;
|
||||
import android.support.test.rule.ActivityTestRule;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.util.AndroidRuntimeException;
|
||||
import android.view.View;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@MediumTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SpringTests {
|
||||
@Rule public final ActivityTestRule<AnimationActivity> mActivityTestRule;
|
||||
public View mView1;
|
||||
public View mView2;
|
||||
|
||||
@Rule
|
||||
public ExpectedException mExpectedException = ExpectedException.none();
|
||||
|
||||
public SpringTests() {
|
||||
mActivityTestRule = new ActivityTestRule<>(AnimationActivity.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
mView1 = mActivityTestRule.getActivity().findViewById(R.id.anim_view);
|
||||
mView2 = mActivityTestRule.getActivity().findViewById(R.id.anim_another_view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that custom properties are supported.
|
||||
*/
|
||||
@Test
|
||||
public void testCustomProperties() {
|
||||
final Object animObj = new Object();
|
||||
FloatPropertyCompat property = new FloatPropertyCompat("") {
|
||||
private float mValue = 0f;
|
||||
@Override
|
||||
public float getValue(Object object) {
|
||||
assertEquals(animObj, object);
|
||||
return mValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Object object, float value) {
|
||||
assertEquals(animObj, object);
|
||||
assertTrue(value >= mValue);
|
||||
mValue = value;
|
||||
}
|
||||
};
|
||||
final SpringAnimation anim = new SpringAnimation(animObj, property, 1f);
|
||||
DynamicAnimation.OnAnimationEndListener listener = mock(
|
||||
DynamicAnimation.OnAnimationEndListener.class);
|
||||
anim.addEndListener(listener);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.start();
|
||||
}
|
||||
});
|
||||
verify(listener, timeout(1000)).onAnimationEnd(anim, false, 1f, 0f);
|
||||
assertEquals(1f, property.getValue(animObj), 0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that spring animation can work with a single property without an object.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueHolder() {
|
||||
final FloatValueHolder floatValueHolder = new FloatValueHolder(0f);
|
||||
DynamicAnimation.OnAnimationUpdateListener updateListener =
|
||||
new DynamicAnimation.OnAnimationUpdateListener() {
|
||||
private float mLastValue = 0f;
|
||||
@Override
|
||||
public void onAnimationUpdate(DynamicAnimation animation, float value, float velocity) {
|
||||
// New value >= value from last frame
|
||||
assertTrue(value >= mLastValue);
|
||||
mLastValue = value;
|
||||
assertEquals(value, floatValueHolder.getValue(), 0f);
|
||||
}
|
||||
};
|
||||
|
||||
DynamicAnimation.OnAnimationUpdateListener mockListener =
|
||||
mock(DynamicAnimation.OnAnimationUpdateListener.class);
|
||||
|
||||
final SpringAnimation anim = new SpringAnimation(floatValueHolder)
|
||||
.addUpdateListener(updateListener).addUpdateListener(mockListener);
|
||||
anim.setSpring(new SpringForce(1000).setDampingRatio(1.2f));
|
||||
|
||||
DynamicAnimation.OnAnimationEndListener listener = mock(
|
||||
DynamicAnimation.OnAnimationEndListener.class);
|
||||
anim.addEndListener(listener);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.setStartValue(0).start();
|
||||
}
|
||||
});
|
||||
|
||||
verify(mockListener, timeout(1000).atLeast(10)).onAnimationUpdate(eq(anim), lt(1000f),
|
||||
any(float.class));
|
||||
verify(listener, timeout(1000)).onAnimationEnd(anim, false, 1000f, 0f);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the final position of the default spring against what's being set through the
|
||||
* constructor.
|
||||
*/
|
||||
@Test
|
||||
public void testGetFinalPosition() {
|
||||
SpringAnimation animation = new SpringAnimation(mView1, DynamicAnimation.TRANSLATION_X, 20);
|
||||
assertEquals(20, animation.getSpring().getFinalPosition(), 0);
|
||||
|
||||
SpringForce spring = new SpringForce();
|
||||
spring.setFinalPosition(25.0f);
|
||||
assertEquals(25.0f, spring.getFinalPosition(), 0.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that for over-damped springs, the higher the damping ratio, the slower it is. Also
|
||||
* verify that critically damped springs finish faster than overdamped springs.
|
||||
*/
|
||||
@Test
|
||||
public void testDampingRatioOverAndCriticallyDamped() {
|
||||
// Compare overdamped springs
|
||||
final SpringAnimation anim1 = new SpringAnimation(mView1, DynamicAnimation.X, 0);
|
||||
final SpringAnimation anim2 = new SpringAnimation(mView2, DynamicAnimation.Y, 0);
|
||||
final SpringAnimation anim3 = new SpringAnimation(mView2, DynamicAnimation.Z, 0);
|
||||
final DynamicAnimation.OnAnimationUpdateListener updateListener =
|
||||
new DynamicAnimation.OnAnimationUpdateListener() {
|
||||
public float position1 = 1000;
|
||||
public float position2 = 1000;
|
||||
public float position3 = 1000;
|
||||
@Override
|
||||
public void onAnimationUpdate(DynamicAnimation animation, float value,
|
||||
float velocity) {
|
||||
if (animation == anim1) {
|
||||
position1 = value;
|
||||
if (position1 == 800) {
|
||||
// first frame
|
||||
assertEquals(position1, position2, 0);
|
||||
assertEquals(position1, position3, 0);
|
||||
} else {
|
||||
assertTrue(position2 > position1);
|
||||
assertTrue(position3 > position2);
|
||||
assertTrue(800 > position3);
|
||||
}
|
||||
} else if (animation == anim2) {
|
||||
position2 = value;
|
||||
} else {
|
||||
position3 = value;
|
||||
}
|
||||
}
|
||||
};
|
||||
final MyEndListener l1 = new MyEndListener();
|
||||
final MyEndListener l2 = new MyEndListener();
|
||||
final MyEndListener l3 = new MyEndListener();
|
||||
|
||||
final DynamicAnimation.OnAnimationEndListener mockListener =
|
||||
mock(DynamicAnimation.OnAnimationEndListener.class);
|
||||
anim1.getSpring().setStiffness(SpringForce.STIFFNESS_HIGH).setDampingRatio(1f);
|
||||
anim2.getSpring().setStiffness(SpringForce.STIFFNESS_HIGH).setDampingRatio(1.5f);
|
||||
anim3.getSpring().setStiffness(SpringForce.STIFFNESS_HIGH).setDampingRatio(2.0f);
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim2.setStartValue(800).addUpdateListener(updateListener).addEndListener(l2)
|
||||
.start();
|
||||
anim3.setStartValue(800).addUpdateListener(updateListener).addEndListener(l3)
|
||||
.addEndListener(mockListener).start();
|
||||
anim1.setStartValue(800).addUpdateListener(updateListener).addEndListener(l1)
|
||||
.start();
|
||||
|
||||
}
|
||||
});
|
||||
// The spring animation with critically-damped spring should return to rest position faster.
|
||||
verify(mockListener, timeout(2000)).onAnimationEnd(anim3, false, 0, 0);
|
||||
assertTrue(l1.endTime > 0);
|
||||
assertTrue(l2.endTime > l1.endTime);
|
||||
assertTrue(l3.endTime > l2.endTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that more underdamped springs are bouncier, and that critically damped springs finish
|
||||
* faster than underdamped springs.
|
||||
*/
|
||||
@Test
|
||||
public void testDampingRatioUnderDamped() {
|
||||
final SpringAnimation anim1 = new SpringAnimation(mView1, DynamicAnimation.ROTATION, 0);
|
||||
final SpringAnimation anim2 = new SpringAnimation(mView2, DynamicAnimation.ROTATION_X, 0);
|
||||
final SpringAnimation anim3 = new SpringAnimation(mView2, DynamicAnimation.ROTATION_Y, 0);
|
||||
|
||||
final DynamicAnimation.OnAnimationUpdateListener updateListener =
|
||||
new DynamicAnimation.OnAnimationUpdateListener() {
|
||||
public float bounceCount1 = 0;
|
||||
public float bounceCount2 = 0;
|
||||
|
||||
public float velocity1 = 0;
|
||||
public float velocity2 = 0;
|
||||
|
||||
@Override
|
||||
public void onAnimationUpdate(DynamicAnimation animation, float value,
|
||||
float velocity) {
|
||||
if (animation == anim1) {
|
||||
if (velocity > 0 && velocity1 < 0) {
|
||||
bounceCount1++;
|
||||
}
|
||||
velocity1 = velocity;
|
||||
} else if (animation == anim2) {
|
||||
velocity2 = velocity;
|
||||
if (velocity > 0 && velocity2 < 0) {
|
||||
bounceCount2++;
|
||||
assertTrue(bounceCount1 > bounceCount2);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
final MyEndListener l1 = new MyEndListener();
|
||||
final MyEndListener l2 = new MyEndListener();
|
||||
final MyEndListener l3 = new MyEndListener();
|
||||
|
||||
final DynamicAnimation.OnAnimationEndListener mockListener =
|
||||
mock(DynamicAnimation.OnAnimationEndListener.class);
|
||||
anim1.getSpring().setStiffness(SpringForce.STIFFNESS_MEDIUM).setDampingRatio(0.3f);
|
||||
anim2.getSpring().setStiffness(SpringForce.STIFFNESS_MEDIUM).setDampingRatio(0.5f);
|
||||
anim3.getSpring().setStiffness(SpringForce.STIFFNESS_MEDIUM).setDampingRatio(1f);
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim1.setStartValue(360).addUpdateListener(updateListener).addEndListener(l1)
|
||||
.start();
|
||||
anim2.setStartValue(360).addUpdateListener(updateListener).addEndListener(l2)
|
||||
.addEndListener(mockListener).start();
|
||||
anim3.setStartValue(360).addEndListener(l3).start();
|
||||
}
|
||||
});
|
||||
// The spring animation with critically-damped spring should return to rest position faster.
|
||||
verify(mockListener, timeout(2000)).onAnimationEnd(anim2, false, 0, 0);
|
||||
assertFalse(anim3.isRunning());
|
||||
assertTrue(l3.endTime > 0);
|
||||
assertTrue(l2.endTime > l3.endTime);
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (anim1.isRunning()) {
|
||||
anim1.cancel();
|
||||
} else {
|
||||
assertTrue(l1.endTime > l2.endTime);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that stiffer spring animations finish sooner than less stiff spring animations. Run
|
||||
* the same verification on different damping ratios.
|
||||
*/
|
||||
@LargeTest
|
||||
@Test
|
||||
public void testStiffness() {
|
||||
float[] dampingRatios = {0.3f, 0.5f, 1f, 5f};
|
||||
final float[] stiffness = {50f, 500f, 1500f, 5000f};
|
||||
DynamicAnimation.ViewProperty[] viewProperties =
|
||||
{DynamicAnimation.SCROLL_X, DynamicAnimation.TRANSLATION_X,
|
||||
DynamicAnimation.TRANSLATION_Y, DynamicAnimation.TRANSLATION_Z};
|
||||
assertEquals(viewProperties.length, stiffness.length);
|
||||
|
||||
final SpringAnimation[] springAnims = new SpringAnimation[stiffness.length];
|
||||
SpringForce[] springs = new SpringForce[stiffness.length];
|
||||
MyEndListener[] listeners = new MyEndListener[stiffness.length];
|
||||
|
||||
// Sets stiffness
|
||||
for (int i = 0; i < stiffness.length; i++) {
|
||||
springs[i] = new SpringForce(0).setStiffness(stiffness[i]);
|
||||
listeners[i] = new MyEndListener();
|
||||
springAnims[i] = new SpringAnimation(mView1, viewProperties[i]).setSpring(springs[i])
|
||||
.addEndListener(listeners[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < dampingRatios.length; i++) {
|
||||
for (int j = 0; j < stiffness.length; j++) {
|
||||
springs[j].setDampingRatio(dampingRatios[i]);
|
||||
springAnims[j].setStartValue(0).setStartVelocity(500);
|
||||
listeners[j].endTime = -1;
|
||||
}
|
||||
DynamicAnimation.OnAnimationEndListener mockListener = mock(
|
||||
DynamicAnimation.OnAnimationEndListener.class);
|
||||
springAnims[1].addEndListener(mockListener);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int j = 0; j < stiffness.length; j++) {
|
||||
springAnims[j].start();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
verify(mockListener, timeout(2000)).onAnimationEnd(springAnims[1], false, 0f, 0f);
|
||||
|
||||
if (springAnims[0].isRunning()) {
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
springAnims[0].cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
for (int j = 1; j < stiffness.length; j++) {
|
||||
// The stiffer spring should finish no later than the less stiff spring.
|
||||
assertTrue(listeners[j - 1].endTime > listeners[j].endTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test negative stiffness and expect exception.
|
||||
*/
|
||||
@Test
|
||||
public void testInvalidStiffness() {
|
||||
SpringForce spring = new SpringForce();
|
||||
mExpectedException.expect(IllegalArgumentException.class);
|
||||
spring.setStiffness(-5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test negative dampingRatio and expect exception.
|
||||
*/
|
||||
@Test
|
||||
public void testInvalidDampingRatio() {
|
||||
SpringForce spring = new SpringForce();
|
||||
mExpectedException.expect(IllegalArgumentException.class);
|
||||
spring.setDampingRatio(-5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an update listener and an end listener, and check that there are no interaction after
|
||||
* removal.
|
||||
*/
|
||||
@Test
|
||||
public void testRemoveListeners() {
|
||||
final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.ALPHA, 0.5f);
|
||||
DynamicAnimation.OnAnimationEndListener endListener = mock(
|
||||
DynamicAnimation.OnAnimationEndListener.class);
|
||||
DynamicAnimation.OnAnimationEndListener removedEndListener = mock(
|
||||
DynamicAnimation.OnAnimationEndListener.class);
|
||||
DynamicAnimation.OnAnimationUpdateListener updateListener = mock(
|
||||
DynamicAnimation.OnAnimationUpdateListener.class);
|
||||
DynamicAnimation.OnAnimationUpdateListener removedUpdateListener = mock(
|
||||
DynamicAnimation.OnAnimationUpdateListener.class);
|
||||
|
||||
anim.addEndListener(removedEndListener);
|
||||
anim.addEndListener(endListener);
|
||||
anim.removeEndListener(removedEndListener);
|
||||
|
||||
anim.addUpdateListener(removedUpdateListener);
|
||||
anim.addUpdateListener(updateListener);
|
||||
anim.removeUpdateListener(removedUpdateListener);
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.start();
|
||||
}
|
||||
});
|
||||
|
||||
verify(endListener, timeout(1000)).onAnimationEnd(anim, false, 0.5f, 0f);
|
||||
verify(updateListener, atLeast(2)).onAnimationUpdate(eq(anim), any(float.class),
|
||||
any(float.class));
|
||||
|
||||
verifyZeroInteractions(removedEndListener);
|
||||
verifyZeroInteractions(removedUpdateListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies stiffness getter returns the right value.
|
||||
*/
|
||||
@Test
|
||||
public void testGetStiffness() {
|
||||
SpringForce spring = new SpringForce();
|
||||
spring.setStiffness(1.0f);
|
||||
assertEquals(1.0f, spring.getStiffness(), 0.0f);
|
||||
spring.setStiffness(2.0f);
|
||||
assertEquals(2.0f, spring.getStiffness(), 0.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies damping ratio getter returns the right value.
|
||||
*/
|
||||
@Test
|
||||
public void testGetDampingRatio() {
|
||||
SpringForce spring = new SpringForce();
|
||||
spring.setDampingRatio(1.0f);
|
||||
assertEquals(1.0f, spring.getDampingRatio(), 0.0f);
|
||||
spring.setDampingRatio(2.0f);
|
||||
assertEquals(2.0f, spring.getDampingRatio(), 0.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that once min and max value threshold does apply to the values in animation.
|
||||
*/
|
||||
@Test
|
||||
public void testSetMinMax() {
|
||||
final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.SCALE_X, 0.0f);
|
||||
anim.setMinValue(0.0f);
|
||||
anim.setMaxValue(1.0f);
|
||||
anim.getSpring().setStiffness(SpringForce.STIFFNESS_HIGH).setDampingRatio(
|
||||
SpringForce.DAMPING_RATIO_HIGH_BOUNCY);
|
||||
|
||||
final DynamicAnimation.OnAnimationUpdateListener mockUpdateListener = mock(
|
||||
DynamicAnimation.OnAnimationUpdateListener.class);
|
||||
final DynamicAnimation.OnAnimationEndListener mockEndListener = mock(
|
||||
DynamicAnimation.OnAnimationEndListener.class);
|
||||
final DynamicAnimation.OnAnimationUpdateListener updateListener =
|
||||
new DynamicAnimation.OnAnimationUpdateListener() {
|
||||
|
||||
@Override
|
||||
public void onAnimationUpdate(DynamicAnimation animation, float value, float velocity) {
|
||||
assertTrue(value >= 0.0f);
|
||||
assertTrue(value <= 1.0f);
|
||||
}
|
||||
};
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.setStartValue(1.0f).setStartVelocity(8000f)
|
||||
.addEndListener(mockEndListener).addUpdateListener(mockUpdateListener)
|
||||
.addUpdateListener(updateListener).start();
|
||||
}});
|
||||
|
||||
verify(mockEndListener, timeout(2000)).onAnimationEnd(anim, false, 0f, 0f);
|
||||
verify(mockUpdateListener, atLeast(2)).onAnimationUpdate(eq(anim), any(float.class),
|
||||
any(float.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies animateToFinalPosition works both when the anim hasn't started and when it's
|
||||
* running.
|
||||
*/
|
||||
@Test
|
||||
public void testAnimateToFinalPosition() throws InterruptedException {
|
||||
final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.SCALE_Y, 0.0f);
|
||||
final DynamicAnimation.OnAnimationEndListener mockEndListener = mock(
|
||||
DynamicAnimation.OnAnimationEndListener.class);
|
||||
anim.addEndListener(mockEndListener);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.animateToFinalPosition(0.0f);
|
||||
}
|
||||
});
|
||||
assertTrue(anim.isRunning());
|
||||
Thread.sleep(100);
|
||||
assertTrue(anim.isRunning());
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.animateToFinalPosition(1.0f);
|
||||
}
|
||||
});
|
||||
|
||||
assertTrue(anim.isRunning());
|
||||
// Verify that it indeed ends at the value from the second animateToFinalPosition() call.
|
||||
verify(mockEndListener, timeout(1500)).onAnimationEnd(anim, false, 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that skip to end will stop the animation, and skips the value to the end value.
|
||||
*/
|
||||
@Test
|
||||
public void testSkipToEnd() {
|
||||
final float finalPosition = 10f;
|
||||
final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.SCROLL_X,
|
||||
finalPosition);
|
||||
final DynamicAnimation.OnAnimationEndListener mockListener =
|
||||
mock(DynamicAnimation.OnAnimationEndListener.class);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.addEndListener(mockListener).setStartValue(200).start();
|
||||
}
|
||||
});
|
||||
assertTrue(anim.isRunning());
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int scrollX = mView1.getScrollX();
|
||||
anim.skipToEnd();
|
||||
// Expect no change in the animation values until next frame.
|
||||
assertEquals(scrollX, mView1.getScrollX());
|
||||
assertTrue(anim.isRunning());
|
||||
}
|
||||
});
|
||||
verify(mockListener, timeout(100).times(1)).onAnimationEnd(anim, false, finalPosition, 0);
|
||||
|
||||
// Also make sure the skipToEnd() call doesn't affect next animation run.
|
||||
final DynamicAnimation.OnAnimationEndListener mockListener2 =
|
||||
mock(DynamicAnimation.OnAnimationEndListener.class);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.addEndListener(mockListener2);
|
||||
anim.animateToFinalPosition(finalPosition + 1000f);
|
||||
}
|
||||
});
|
||||
// Verify that the animation doesn't finish right away
|
||||
verify(mockListener2, timeout(300).times(0)).onAnimationEnd(any(DynamicAnimation.class),
|
||||
any(boolean.class), any(float.class), any(float.class));
|
||||
|
||||
// But the animation should eventually finish.
|
||||
verify(mockListener, timeout(1000).times(1)).onAnimationEnd(anim, false,
|
||||
finalPosition + 1000f, 0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the min visible change does affect how soon spring animations end.
|
||||
*/
|
||||
public void testScaleMinChange() {
|
||||
FloatValueHolder valueHolder = new FloatValueHolder(0.5f);
|
||||
final SpringAnimation anim = new SpringAnimation(valueHolder);
|
||||
DynamicAnimation.OnAnimationUpdateListener mockListener =
|
||||
mock(DynamicAnimation.OnAnimationUpdateListener.class);
|
||||
anim.addUpdateListener(mockListener);
|
||||
|
||||
final DynamicAnimation.OnAnimationEndListener endListener =
|
||||
mock(DynamicAnimation.OnAnimationEndListener.class);
|
||||
anim.addEndListener(endListener);
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.animateToFinalPosition(1f);
|
||||
}
|
||||
});
|
||||
|
||||
verify(endListener, timeout(500)).onAnimationEnd(anim, false, 0, 0);
|
||||
verify(mockListener, atMost(5)).onAnimationUpdate(eq(anim), anyFloat(), anyFloat());
|
||||
|
||||
assertEquals(DynamicAnimation.MIN_VISIBLE_CHANGE_PIXELS, anim.getMinimumVisibleChange());
|
||||
|
||||
// Set the right threshold and start again.
|
||||
anim.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);
|
||||
anim.setStartValue(0.5f);
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
anim.animateToFinalPosition(1f);
|
||||
}
|
||||
});
|
||||
|
||||
verify(endListener, timeout(2000)).onAnimationEnd(anim, false, 0, 0);
|
||||
verify(mockListener, atLeast(10)).onAnimationUpdate(eq(anim), anyFloat(), anyFloat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure all the properties getter works.
|
||||
*/
|
||||
@Test
|
||||
public void testAllProperties() {
|
||||
final DynamicAnimation.ViewProperty[] properties = {
|
||||
DynamicAnimation.ALPHA, DynamicAnimation.TRANSLATION_X,
|
||||
DynamicAnimation.TRANSLATION_Y, DynamicAnimation.TRANSLATION_Z,
|
||||
DynamicAnimation.SCALE_X, DynamicAnimation.SCALE_Y, DynamicAnimation.ROTATION,
|
||||
DynamicAnimation.ROTATION_X, DynamicAnimation.ROTATION_Y,
|
||||
DynamicAnimation.X, DynamicAnimation.Y, DynamicAnimation.Z,
|
||||
DynamicAnimation.SCROLL_X, DynamicAnimation.SCROLL_Y,
|
||||
};
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mView1.setAlpha(0f);
|
||||
mView1.setTranslationX(0f);
|
||||
mView1.setTranslationY(0f);
|
||||
ViewCompat.setTranslationZ(mView1, 0f);
|
||||
|
||||
mView1.setScaleX(0f);
|
||||
mView1.setScaleY(0f);
|
||||
|
||||
mView1.setRotation(0f);
|
||||
mView1.setRotationX(0f);
|
||||
mView1.setRotationY(0f);
|
||||
|
||||
mView1.setX(0f);
|
||||
mView1.setY(0f);
|
||||
ViewCompat.setZ(mView1, 0f);
|
||||
|
||||
mView1.setScrollX(0);
|
||||
mView1.setScrollY(0);
|
||||
}
|
||||
});
|
||||
|
||||
final SpringAnimation[] anims = new SpringAnimation[properties.length];
|
||||
final DynamicAnimation.OnAnimationUpdateListener[] mockListeners =
|
||||
new DynamicAnimation.OnAnimationUpdateListener[properties.length];
|
||||
for (int i = 0; i < properties.length; i++) {
|
||||
anims[i] = new SpringAnimation(mView1, properties[i], 1);
|
||||
final int finalI = i;
|
||||
anims[i].addUpdateListener(
|
||||
new DynamicAnimation.OnAnimationUpdateListener() {
|
||||
boolean mIsFirstFrame = true;
|
||||
@Override
|
||||
public void onAnimationUpdate(DynamicAnimation animation, float value,
|
||||
float velocity) {
|
||||
if (mIsFirstFrame) {
|
||||
assertEquals(value, 0f, 0f);
|
||||
}
|
||||
mIsFirstFrame = false;
|
||||
}
|
||||
});
|
||||
mockListeners[i] = mock(DynamicAnimation.OnAnimationUpdateListener.class);
|
||||
anims[i].addUpdateListener(mockListeners[i]);
|
||||
}
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = properties.length - 1; i >= 0; i--) {
|
||||
anims[i].start();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < properties.length; i++) {
|
||||
int timeout = i == 0 ? 100 : 0;
|
||||
verify(mockListeners[i], timeout(timeout).atLeast(1)).onAnimationUpdate(
|
||||
any(SpringAnimation.class), any(float.class), any(float.class));
|
||||
}
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < properties.length; i++) {
|
||||
anims[i].cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test start() on a test thread.
|
||||
*/
|
||||
@Test
|
||||
public void testStartOnNonMainThread() {
|
||||
mExpectedException.expect(AndroidRuntimeException.class);
|
||||
SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.ALPHA, 0f);
|
||||
anim.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test cancel() on a test thread.
|
||||
*/
|
||||
@Test
|
||||
public void testCancelOnNonMainThread() {
|
||||
mExpectedException.expect(AndroidRuntimeException.class);
|
||||
SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.ALPHA, 0f);
|
||||
anim.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test skipToEnd() on a test thread.
|
||||
*/
|
||||
@Test
|
||||
public void testSkipToEndOnNonMainThread() {
|
||||
mExpectedException.expect(AndroidRuntimeException.class);
|
||||
SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.ALPHA, 0f);
|
||||
anim.skipToEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test invalid start condition: no spring position specified, final position > max value,
|
||||
* and final position < min. Expect exception in all these cases.
|
||||
*/
|
||||
@Test
|
||||
public void testInvalidStartingCondition() {
|
||||
final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.X);
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Expect exception from not setting spring final position before calling start.
|
||||
try {
|
||||
anim.start();
|
||||
fail("No exception is thrown when calling start() from non-main thread.");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
}
|
||||
|
||||
// Expect exception from having a final position < min value
|
||||
try {
|
||||
anim.setMinValue(50);
|
||||
// Final position < min value, expect exception.
|
||||
anim.setStartValue(50).animateToFinalPosition(40);
|
||||
fail("No exception is thrown when spring position is less than min value.");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
}
|
||||
|
||||
// Expect exception from not setting spring final position before calling start.
|
||||
try {
|
||||
anim.setMaxValue(60);
|
||||
// Final position < min value, expect exception.
|
||||
anim.setStartValue(60).animateToFinalPosition(70);
|
||||
fail("No exception is thrown when spring position is greater than max value.");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Try skipToEnd() on an undamped spring, and expect exception.
|
||||
*/
|
||||
@Test
|
||||
public void testUndampedSpring() {
|
||||
final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.Y);
|
||||
anim.setSpring(new SpringForce(10).setDampingRatio(0));
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Expect exception for ending an undamped spring.
|
||||
try {
|
||||
anim.skipToEnd();
|
||||
fail("No exception is thrown when calling skipToEnd() on an undamped spring");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
static class MyEndListener implements DynamicAnimation.OnAnimationEndListener {
|
||||
public long endTime = -1;
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value,
|
||||
float velocity) {
|
||||
endTime = SystemClock.uptimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue