dynamic-animation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
@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 more underdamped springs are bouncier, and that critically damped springs finish
     * faster than underdamped springs.
     */
Verify that more underdamped springs are bouncier, and that critically damped springs finish
faster than underdamped springs.
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();
            }
        });
        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);
                }
            }
        });
    }
@ 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 ( ) ; } } ) ; 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 more underdamped springs are bouncier, and that critically damped springs finish
 faster than underdamped springs.
Verify that more underdamped springs are bouncier and that critically damped springs finish faster than underdamped springs .
// The spring animation with critically-damped spring should return to rest position faster.