Loading core/java/android/animation/AnimatorSet.java +20 −2 Original line number Original line Diff line number Diff line Loading @@ -1346,8 +1346,26 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim } } // Set the child animators to the right end: // Set the child animators to the right end: if (mShouldResetValuesAtStart) { if (mShouldResetValuesAtStart) { if (isInitialized()) { skipToEndValue(!mReversing); } else if (mReversing) { // Reversing but haven't initialized all the children yet. initChildren(); initChildren(); skipToEndValue(!mReversing); skipToEndValue(!mReversing); } else { // If not all children are initialized and play direction is forward for (int i = mEvents.size() - 1; i >= 0; i--) { if (mEvents.get(i).mEvent == AnimationEvent.ANIMATION_DELAY_ENDED) { Animator anim = mEvents.get(i).mNode.mAnimation; // Only reset the animations that have been initialized to start value, // so that if they are defined without a start value, they will get the // values set at the right time (i.e. the next animation run) if (anim.isInitialized()) { anim.skipToEndValue(true); } } } } } } if (mReversing || mStartDelay == 0 || mSeekState.isActive()) { if (mReversing || mStartDelay == 0 || mSeekState.isActive()) { Loading core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java +65 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue; import android.util.Property; import android.util.Property; import android.view.View; import android.view.View; import androidx.annotation.NonNull; import androidx.test.annotation.UiThreadTest; import androidx.test.annotation.UiThreadTest; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; import androidx.test.rule.ActivityTestRule; import androidx.test.rule.ActivityTestRule; Loading @@ -36,6 +37,8 @@ import org.junit.Rule; import org.junit.Test; import org.junit.Test; import java.util.ArrayList; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @SmallTest @SmallTest public class AnimatorSetActivityTest { public class AnimatorSetActivityTest { Loading Loading @@ -613,6 +616,68 @@ public class AnimatorSetActivityTest { }); }); } } @Test public void initAfterStartNotification() throws Throwable { Property<int[], Integer> property = new Property<>(Integer.class, "firstValue") { @Override public Integer get(int[] target) { throw new IllegalStateException("Shouldn't be called"); } @Override public void set(int[] target, Integer value) { target[0] = value; } }; int[] target = new int[1]; ObjectAnimator animator1 = ObjectAnimator.ofInt(target, property, 0, 100); ObjectAnimator animator2 = ObjectAnimator.ofInt(target, property, 0, 100); ObjectAnimator animator3 = ObjectAnimator.ofInt(target, property, 0, 100); animator1.setDuration(10); animator2.setDuration(10); animator3.setDuration(10); AnimatorSet set = new AnimatorSet(); set.playSequentially(animator1, animator2, animator3); final int[] values = new int[4]; animator2.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(@NonNull Animator animation, boolean isReverse) { values[0] = target[0]; animator2.setIntValues(target[0], target[0] + 100); } @Override public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) { values[1] = target[0]; } }); animator3.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(@NonNull Animator animation, boolean isReverse) { values[2] = target[0]; animator3.setIntValues(target[0], target[0] + 100); } @Override public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) { values[3] = target[0]; } }); final CountDownLatch latch = new CountDownLatch(1); set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) { latch.countDown(); } }); mActivityRule.runOnUiThread(() -> set.start()); assertTrue(latch.await(1, TimeUnit.SECONDS)); assertEquals(100, values[0]); assertEquals(200, values[1]); assertEquals(200, values[2]); assertEquals(300, values[3]); } /** /** * Check that the animator list contains exactly the given animators and nothing else. * Check that the animator list contains exactly the given animators and nothing else. */ */ Loading Loading
core/java/android/animation/AnimatorSet.java +20 −2 Original line number Original line Diff line number Diff line Loading @@ -1346,8 +1346,26 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim } } // Set the child animators to the right end: // Set the child animators to the right end: if (mShouldResetValuesAtStart) { if (mShouldResetValuesAtStart) { if (isInitialized()) { skipToEndValue(!mReversing); } else if (mReversing) { // Reversing but haven't initialized all the children yet. initChildren(); initChildren(); skipToEndValue(!mReversing); skipToEndValue(!mReversing); } else { // If not all children are initialized and play direction is forward for (int i = mEvents.size() - 1; i >= 0; i--) { if (mEvents.get(i).mEvent == AnimationEvent.ANIMATION_DELAY_ENDED) { Animator anim = mEvents.get(i).mNode.mAnimation; // Only reset the animations that have been initialized to start value, // so that if they are defined without a start value, they will get the // values set at the right time (i.e. the next animation run) if (anim.isInitialized()) { anim.skipToEndValue(true); } } } } } } if (mReversing || mStartDelay == 0 || mSeekState.isActive()) { if (mReversing || mStartDelay == 0 || mSeekState.isActive()) { Loading
core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java +65 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue; import android.util.Property; import android.util.Property; import android.view.View; import android.view.View; import androidx.annotation.NonNull; import androidx.test.annotation.UiThreadTest; import androidx.test.annotation.UiThreadTest; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; import androidx.test.rule.ActivityTestRule; import androidx.test.rule.ActivityTestRule; Loading @@ -36,6 +37,8 @@ import org.junit.Rule; import org.junit.Test; import org.junit.Test; import java.util.ArrayList; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @SmallTest @SmallTest public class AnimatorSetActivityTest { public class AnimatorSetActivityTest { Loading Loading @@ -613,6 +616,68 @@ public class AnimatorSetActivityTest { }); }); } } @Test public void initAfterStartNotification() throws Throwable { Property<int[], Integer> property = new Property<>(Integer.class, "firstValue") { @Override public Integer get(int[] target) { throw new IllegalStateException("Shouldn't be called"); } @Override public void set(int[] target, Integer value) { target[0] = value; } }; int[] target = new int[1]; ObjectAnimator animator1 = ObjectAnimator.ofInt(target, property, 0, 100); ObjectAnimator animator2 = ObjectAnimator.ofInt(target, property, 0, 100); ObjectAnimator animator3 = ObjectAnimator.ofInt(target, property, 0, 100); animator1.setDuration(10); animator2.setDuration(10); animator3.setDuration(10); AnimatorSet set = new AnimatorSet(); set.playSequentially(animator1, animator2, animator3); final int[] values = new int[4]; animator2.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(@NonNull Animator animation, boolean isReverse) { values[0] = target[0]; animator2.setIntValues(target[0], target[0] + 100); } @Override public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) { values[1] = target[0]; } }); animator3.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(@NonNull Animator animation, boolean isReverse) { values[2] = target[0]; animator3.setIntValues(target[0], target[0] + 100); } @Override public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) { values[3] = target[0]; } }); final CountDownLatch latch = new CountDownLatch(1); set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) { latch.countDown(); } }); mActivityRule.runOnUiThread(() -> set.start()); assertTrue(latch.await(1, TimeUnit.SECONDS)); assertEquals(100, values[0]); assertEquals(200, values[1]); assertEquals(200, values[2]); assertEquals(300, values[3]); } /** /** * Check that the animator list contains exactly the given animators and nothing else. * Check that the animator list contains exactly the given animators and nothing else. */ */ Loading