| /* |
| * Copyright (C) 2015 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.transition.cts; |
| |
| import static com.android.compatibility.common.util.CtsMockitoUtils.within; |
| |
| import static org.hamcrest.CoreMatchers.allOf; |
| import static org.hamcrest.Matchers.greaterThanOrEqualTo; |
| import static org.hamcrest.Matchers.lessThan; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertThat; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| import static org.mockito.Matchers.any; |
| import static org.mockito.Matchers.eq; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.never; |
| import static org.mockito.Mockito.times; |
| import static org.mockito.Mockito.verify; |
| |
| import android.animation.Animator; |
| import android.graphics.Rect; |
| import android.os.SystemClock; |
| import android.support.test.filters.MediumTest; |
| import android.support.test.runner.AndroidJUnit4; |
| import android.transition.ArcMotion; |
| import android.transition.AutoTransition; |
| import android.transition.ChangeBounds; |
| import android.transition.CircularPropagation; |
| import android.transition.PathMotion; |
| import android.transition.Scene; |
| import android.transition.Transition; |
| import android.transition.Transition.EpicenterCallback; |
| import android.transition.Transition.TransitionListener; |
| import android.transition.TransitionListenerAdapter; |
| import android.transition.TransitionManager; |
| import android.transition.TransitionPropagation; |
| import android.transition.TransitionValues; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.view.animation.AccelerateInterpolator; |
| import android.widget.ImageView; |
| import android.widget.RelativeLayout; |
| import android.widget.TextView; |
| |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| import java.util.HashMap; |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.TimeUnit; |
| |
| @MediumTest |
| @RunWith(AndroidJUnit4.class) |
| public class TransitionTest extends BaseTransitionTest { |
| @Test |
| public void testAddListener() throws Throwable { |
| startTransition(R.layout.scene1); |
| waitForStart(); |
| |
| final Transition.TransitionListener listener2 = mock(Transition.TransitionListener.class); |
| |
| mActivityRule.runOnUiThread(() -> { |
| AutoTransition autoTransition = new AutoTransition(); |
| autoTransition.setDuration(100); |
| autoTransition.addListener(listener2); |
| Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, mActivity); |
| TransitionManager.go(scene, autoTransition); |
| }); |
| |
| waitForStart(listener2); |
| |
| verify(mListener, times(1)).onTransitionPause(any()); |
| verify(mListener, times(1)).onTransitionResume(any()); |
| verify(mListener, never()).onTransitionCancel(any()); |
| verify(mListener, never()).onTransitionEnd(any()); |
| verify(mListener, times(1)).onTransitionStart(any()); |
| |
| verify(listener2, never()).onTransitionPause(any()); |
| verify(listener2, never()).onTransitionResume(any()); |
| verify(listener2, never()).onTransitionCancel(any()); |
| verify(listener2, never()).onTransitionEnd(any()); |
| verify(listener2, times(1)).onTransitionStart(any()); |
| endTransition(); |
| } |
| |
| @Test |
| public void testRemoveListener() throws Throwable { |
| startTransition(R.layout.scene1); |
| waitForStart(); |
| |
| mActivityRule.runOnUiThread(() -> mTransition.removeListener(mListener)); |
| |
| SystemClock.sleep(250); |
| verify(mListener, never()).onTransitionEnd(any()); |
| } |
| |
| @Test |
| public void testAddTargetId() throws Throwable { |
| enterScene(R.layout.scene4); |
| assertNotNull(mTransition.getTargetIds()); |
| assertTrue(mTransition.getTargetIds().isEmpty()); |
| mTransition.addTarget(R.id.holder); |
| mTransition.addTarget(R.id.hello); |
| assertEquals(2, mTransition.getTargetIds().size()); |
| startTransition(R.layout.scene1); |
| assertEquals(1, mTargets.size()); |
| assertEquals(R.id.hello, mTargets.get(0).getId()); |
| endTransition(); |
| } |
| |
| @Test |
| public void testRemoveTargetId() throws Throwable { |
| enterScene(R.layout.scene4); |
| mTransition.addTarget(R.id.holder); |
| mTransition.addTarget(R.id.hello); |
| mTransition.addTarget(R.id.redSquare); |
| assertEquals(3, mTransition.getTargetIds().size()); |
| mTransition.removeTarget(0); // nothing should happen |
| mTransition.removeTarget(R.id.redSquare); |
| assertEquals(2, mTransition.getTargetIds().size()); |
| |
| startTransition(R.layout.scene1); |
| assertEquals(1, mTargets.size()); |
| assertEquals(R.id.hello, mTargets.get(0).getId()); |
| endTransition(); |
| } |
| |
| @Test |
| public void testAddTargetClass() throws Throwable { |
| enterScene(R.layout.scene4); |
| assertNull(mTransition.getTargetTypes()); |
| mTransition.addTarget(RelativeLayout.class); |
| mTransition.addTarget(TextView.class); |
| assertEquals(2, mTransition.getTargetTypes().size()); |
| startTransition(R.layout.scene1); |
| assertEquals(1, mTargets.size()); |
| assertTrue(mTargets.get(0) instanceof TextView); |
| endTransition(); |
| } |
| |
| @Test |
| public void testRemoveTargetClass() throws Throwable { |
| enterScene(R.layout.scene4); |
| mTransition.addTarget(TextView.class); |
| mTransition.addTarget(View.class); |
| mTransition.addTarget(RelativeLayout.class); |
| assertEquals(3, mTransition.getTargetTypes().size()); |
| mTransition.removeTarget(ImageView.class); // should do nothing |
| mTransition.removeTarget(View.class); |
| assertEquals(2, mTransition.getTargetTypes().size()); |
| startTransition(R.layout.scene1); |
| assertEquals(1, mTargets.size()); |
| assertTrue(mTargets.get(0) instanceof TextView); |
| endTransition(); |
| } |
| |
| @Test |
| public void testAddTargetView() throws Throwable { |
| enterScene(R.layout.scene1); |
| |
| final View[] target = new View[1]; |
| mActivityRule.runOnUiThread(() -> target[0] = mActivity.findViewById(R.id.hello)); |
| mTransition.addTarget(target[0]); |
| assertEquals(1, mTransition.getTargets().size()); |
| mActivityRule.runOnUiThread(() -> { |
| TransitionManager.beginDelayedTransition(mSceneRoot, mTransition); |
| target[0].setVisibility(View.GONE); |
| }); |
| waitForStart(); |
| assertEquals(1, mTargets.size()); |
| assertEquals(target[0], mTargets.get(0)); |
| endTransition(); |
| } |
| |
| @Test |
| public void testRemoveTargetView() throws Throwable { |
| enterScene(R.layout.scene1); |
| |
| final View[] target = new View[3]; |
| mActivityRule.runOnUiThread(() -> { |
| target[0] = mActivity.findViewById(R.id.hello); |
| target[1] = mActivity.findViewById(R.id.greenSquare); |
| target[2] = mActivity.findViewById(R.id.redSquare); |
| }); |
| |
| mTransition.addTarget(target[0]); |
| mTransition.addTarget(target[1]); |
| assertEquals(2, mTransition.getTargets().size()); |
| mTransition.removeTarget(target[2]); // should do nothing |
| mTransition.removeTarget(target[1]); |
| assertEquals(1, mTransition.getTargets().size()); |
| mActivityRule.runOnUiThread(() -> { |
| TransitionManager.beginDelayedTransition(mSceneRoot, mTransition); |
| target[0].setVisibility(View.GONE); |
| }); |
| waitForStart(); |
| assertEquals(1, mTargets.size()); |
| assertEquals(target[0], mTargets.get(0)); |
| endTransition(); |
| } |
| |
| @Test |
| public void testAddTargetName() throws Throwable { |
| enterScene(R.layout.scene4); |
| assertNull(mTransition.getTargetNames()); |
| mTransition.addTarget("red"); |
| mTransition.addTarget("holder"); |
| assertEquals(2, mTransition.getTargetNames().size()); |
| assertEquals(0, mTargets.size()); |
| startTransition(R.layout.scene2); |
| assertEquals(1, mTargets.size()); |
| assertEquals(R.id.redSquare, mTargets.get(0).getId()); |
| endTransition(); |
| } |
| |
| @Test |
| public void testRemoveTargetName() throws Throwable { |
| enterScene(R.layout.scene4); |
| mTransition.addTarget("holder"); |
| mTransition.addTarget("red"); |
| mTransition.addTarget("green"); |
| assertEquals(3, mTransition.getTargetNames().size()); |
| mTransition.removeTarget("purple"); // should do nothing |
| // try to force a different String instance |
| String greenName = new StringBuilder("gre").append("en").toString(); |
| mTransition.removeTarget(greenName); |
| assertEquals(2, mTransition.getTargetNames().size()); |
| startTransition(R.layout.scene1); |
| assertEquals(1, mTargets.size()); |
| assertEquals(R.id.redSquare, mTargets.get(0).getId()); |
| endTransition(); |
| } |
| |
| @Test |
| public void testIsTransitionRequired() throws Throwable { |
| enterScene(R.layout.scene1); |
| mTransition = new NotRequiredTransition(); |
| assertFalse(mTransition.isTransitionRequired(null, null)); |
| resetListener(); |
| mActivityRule.runOnUiThread(() -> { |
| TransitionManager.beginDelayedTransition(mSceneRoot, mTransition); |
| mActivity.findViewById(R.id.hello).setVisibility(View.GONE); |
| }); |
| waitForStart(); |
| assertEquals(0, mTargets.size()); |
| endTransition(); |
| } |
| |
| @Test |
| public void testCanRemoveViews() throws Throwable { |
| enterScene(R.layout.scene1); |
| assertFalse(mTransition.canRemoveViews()); |
| mTransition.addListener(new TransitionListener() { |
| @Override |
| public void onTransitionStart(Transition transition) { |
| assertTrue(transition.canRemoveViews()); |
| } |
| |
| @Override |
| public void onTransitionEnd(Transition transition) { |
| } |
| |
| @Override |
| public void onTransitionCancel(Transition transition) { |
| } |
| |
| @Override |
| public void onTransitionPause(Transition transition) { |
| } |
| |
| @Override |
| public void onTransitionResume(Transition transition) { |
| } |
| }); |
| startTransition(R.layout.scene2); |
| } |
| |
| @Test |
| public void testExcludeChildrenView() throws Throwable { |
| View layout1 = loadLayout(R.layout.scene1); |
| Scene scene1 = loadScene(layout1); |
| enterScene(scene1); |
| View holder1 = layout1.findViewById(R.id.holder); |
| mTransition.excludeChildren(holder1, true); |
| View layout2 = loadLayout(R.layout.scene2); |
| Scene scene2 = loadScene(layout2); |
| View holder2 = layout2.findViewById(R.id.holder); |
| mTransition.excludeChildren(holder2, true); |
| startTransition(scene2); |
| // Should already be ended, since no children are transitioning |
| verify(mListener, times(1)).onTransitionEnd(any()); |
| |
| mTransition.excludeChildren(holder1, false); // remove it |
| mTransition.excludeChildren(holder2, false); // remove it |
| resetListener(); |
| startTransition(scene1); |
| verify(mListener, never()).onTransitionEnd(any()); // it is running as expected |
| endTransition(); |
| } |
| |
| @Test |
| public void testExcludeChildrenId() throws Throwable { |
| enterScene(R.layout.scene1); |
| mTransition.excludeChildren(R.id.holder, true); |
| startTransition(R.layout.scene2); |
| // Should already be ended, since no children are transitioning |
| verify(mListener, times(1)).onTransitionEnd(any()); |
| |
| resetListener(); |
| mTransition.excludeChildren(R.id.holder, false); // remove it |
| startTransition(R.layout.scene1); |
| verify(mListener, never()).onTransitionEnd(any()); // it is running as expected |
| endTransition(); |
| } |
| |
| @Test |
| public void testExcludeChildrenClass() throws Throwable { |
| enterScene(R.layout.scene1); |
| mTransition.excludeChildren(RelativeLayout.class, true); |
| startTransition(R.layout.scene2); |
| // Should already be ended, since no children are transitioning |
| verify(mListener, times(1)).onTransitionEnd(any()); |
| |
| resetListener(); |
| mTransition.excludeChildren(RelativeLayout.class, false); // remove it |
| startTransition(R.layout.scene1); |
| verify(mListener, never()).onTransitionEnd(any()); // it is running as expected |
| endTransition(); |
| } |
| |
| @Test |
| public void testExcludeTargetView() throws Throwable { |
| View layout1 = loadLayout(R.layout.scene1); |
| Scene scene1 = loadScene(layout1); |
| enterScene(R.layout.scene1); |
| View redSquare1 = layout1.findViewById(R.id.redSquare); |
| mTransition.excludeTarget(redSquare1, true); |
| startTransition(R.layout.scene7); |
| waitForEnd(600); |
| |
| mTransition.excludeTarget(redSquare1, false); // remove it |
| resetListener(); |
| startTransition(scene1); |
| verify(mListener, never()).onTransitionEnd(any()); // it is running as expected |
| endTransition(); |
| } |
| |
| @Test |
| public void testExcludeTargetId() throws Throwable { |
| enterScene(R.layout.scene1); |
| mTransition.excludeTarget(R.id.redSquare, true); |
| startTransition(R.layout.scene7); |
| // Should already be ended, since no children are transitioning |
| verify(mListener, times(1)).onTransitionEnd(any()); |
| |
| resetListener(); |
| mTransition.excludeTarget(R.id.redSquare, false); // remove it |
| startTransition(R.layout.scene1); |
| verify(mListener, never()).onTransitionEnd(any()); // it is running as expected |
| endTransition(); |
| } |
| |
| @Test |
| public void testExcludeTargetClass() throws Throwable { |
| enterScene(R.layout.scene1); |
| mTransition.excludeTarget(TextView.class, true); |
| startTransition(R.layout.scene3); |
| // Should already be ended, since no children are transitioning |
| verify(mListener, times(1)).onTransitionEnd(any()); |
| |
| resetListener(); |
| mTransition.excludeTarget(TextView.class, false); // remove it |
| startTransition(R.layout.scene1); |
| verify(mListener, never()).onTransitionEnd(any()); // it is running as expected |
| endTransition(); |
| } |
| |
| @Test |
| public void testExcludeTargetName() throws Throwable { |
| enterScene(R.layout.scene1); |
| mTransition.excludeTarget("hello", true); |
| startTransition(R.layout.scene3); |
| // Should already be ended, since no children are transitioning |
| verify(mListener, times(1)).onTransitionEnd(any()); |
| |
| resetListener(); |
| mTransition.excludeTarget("hello", false); // remove it |
| startTransition(R.layout.scene1); |
| verify(mListener, never()).onTransitionEnd(any()); // it is running as expected |
| endTransition(); |
| } |
| |
| @Test |
| public void testDuration() throws Throwable { |
| assertEquals(-1, mTransition.getDuration()); |
| enterScene(R.layout.scene1); |
| mTransition.setDuration(500); |
| assertEquals(500, mTransition.getDuration()); |
| DurationListener durationListener = new DurationListener(); |
| mTransition.addListener(durationListener); |
| startTransition(R.layout.scene3); |
| waitForEnd(800); |
| assertThat(durationListener.getDuration(), |
| allOf(greaterThanOrEqualTo(500L), lessThan(900L))); |
| } |
| |
| @Test |
| public void testEpicenter() throws Throwable { |
| assertNull(mTransition.getEpicenter()); |
| EpicenterCallback callback = new EpicenterCallback() { |
| @Override |
| public Rect onGetEpicenter(Transition transition) { |
| return new Rect(0, 0, 1, 1); |
| } |
| }; |
| mTransition.setEpicenterCallback(callback); |
| assertSame(callback, mTransition.getEpicenterCallback()); |
| assertEquals(new Rect(0, 0, 1, 1), mTransition.getEpicenter()); |
| } |
| |
| @Test |
| public void testInterpolator() throws Throwable { |
| enterScene(R.layout.scene1); |
| View redSquare = mActivity.findViewById(R.id.redSquare); |
| CaptureAnimatorTransition transition = new CaptureAnimatorTransition(); |
| assertNull(transition.getInterpolator()); |
| AccelerateInterpolator interpolator = new AccelerateInterpolator(); |
| transition.setInterpolator(interpolator); |
| assertSame(interpolator, transition.getInterpolator()); |
| mTransition = transition; |
| resetListener(); |
| startTransition(R.layout.scene4); |
| assertFalse(transition.animators.isEmpty()); |
| Animator animator = transition.animators.get(redSquare); |
| Animator.AnimatorListener listener = transition.listeners.get(redSquare); |
| verify(listener, within(100)).onAnimationStart(any(), eq(false)); |
| assertSame(interpolator, animator.getInterpolator()); |
| endTransition(); |
| } |
| |
| @Test |
| public void testName() throws Throwable { |
| assertEquals("android.transition.cts.BaseTransitionTest$TestTransition", |
| mTransition.getName()); |
| } |
| |
| @Test |
| public void testPathMotion() throws Throwable { |
| PathMotion pathMotion = new ArcMotion(); |
| mTransition.setPathMotion(pathMotion); |
| assertEquals(pathMotion, mTransition.getPathMotion()); |
| } |
| |
| @Test |
| public void testPropagation() throws Throwable { |
| enterScene(R.layout.scene1); |
| CaptureAnimatorTransition transition = new CaptureAnimatorTransition(); |
| mTransition = transition; |
| TransitionPropagation yPropagation = new TransitionPropagation() { |
| private static final String TOP = "top value"; |
| private final String[] PROPERTIES = {TOP}; |
| |
| @Override |
| public long getStartDelay(ViewGroup viewGroup, Transition transition, |
| TransitionValues startValues, TransitionValues endValues) { |
| int startTop = startValues == null ? 0 : (Integer) startValues.values.get(TOP); |
| int endTop = endValues == null ? 0 : (Integer) endValues.values.get(TOP); |
| return (startTop == 0) ? endTop : startTop; |
| } |
| |
| @Override |
| public void captureValues(TransitionValues transitionValues) { |
| if (transitionValues.view != null) { |
| transitionValues.values.put(TOP, transitionValues.view.getTop()); |
| } |
| } |
| |
| @Override |
| public String[] getPropagationProperties() { |
| return PROPERTIES; |
| } |
| }; |
| mTransition.setPropagation(yPropagation); |
| resetListener(); |
| |
| View redSquare = mActivity.findViewById(R.id.redSquare); |
| View greenSquare = mActivity.findViewById(R.id.greenSquare); |
| int diffTop = greenSquare.getTop() - redSquare.getTop(); |
| startTransition(R.layout.scene4); |
| Animator redSquareAnimator = transition.animators.get(redSquare); |
| Animator greenSquareAnimator = transition.animators.get(greenSquare); |
| Animator.AnimatorListener listener = transition.listeners.get(redSquare); |
| verify(listener, within(100)).onAnimationStart(any(), eq(false)); |
| assertEquals(0, redSquareAnimator.getStartDelay()); |
| assertEquals(diffTop, greenSquareAnimator.getStartDelay()); |
| endTransition(); |
| } |
| |
| @Test |
| public void testSetPropagation() throws Throwable { |
| Transition transition = new ChangeBounds(); |
| assertNull(transition.getPropagation()); |
| TransitionPropagation propagation = new CircularPropagation(); |
| transition.setPropagation(propagation); |
| assertSame(propagation, transition.getPropagation()); |
| } |
| |
| @Test |
| public void testStartDelay() throws Throwable { |
| CaptureAnimatorTransition transition = new CaptureAnimatorTransition(); |
| mTransition = transition; |
| resetListener(); |
| enterScene(R.layout.scene1); |
| View redSquare = mActivity.findViewById(R.id.redSquare); |
| |
| assertEquals(-1, mTransition.getStartDelay()); |
| mTransition.setStartDelay(200); |
| assertEquals(200, mTransition.getStartDelay()); |
| |
| startTransition(R.layout.scene4); |
| |
| Animator animator = transition.animators.get(redSquare); |
| assertFalse(animator.isRunning()); |
| Animator.AnimatorListener listener = transition.listeners.get(redSquare); |
| verify(listener, within(250)).onAnimationStart(any(), eq(false)); |
| endTransition(); |
| } |
| |
| @Test |
| public void testTransitionValues() throws Throwable { |
| enterScene(R.layout.scene1); |
| CheckTransitionValuesTransition transition = new CheckTransitionValuesTransition(); |
| mTransition = transition; |
| mTransition.setDuration(10); |
| resetListener(); |
| startTransition(R.layout.scene2); |
| assertTrue(transition.onDisappearCalled.await(500, TimeUnit.MILLISECONDS)); |
| assertTrue(transition.onAppearCalled.await(500, TimeUnit.MILLISECONDS)); |
| // The transition has all the asserts in it, so we can just end it now. |
| endTransition(); |
| } |
| |
| @Test |
| public void testMatchOrder() throws Throwable { |
| mTransition = new ChangeBounds(); |
| resetListener(); |
| enterScene(R.layout.scene1); |
| startTransition(R.layout.scene8); |
| |
| // scene 8 swaps the ids, but not the names. No transition should happen. |
| waitForEnd(0); |
| |
| // now change the match order to prefer the id |
| mTransition.setMatchOrder(new int[] {Transition.MATCH_ID, Transition.MATCH_NAME}); |
| |
| resetListener(); |
| startTransition(R.layout.scene1); |
| verify(mListener, never()).onTransitionEnd(any()); // it is running as expected |
| waitForEnd(400); |
| } |
| |
| @Test |
| public void testGetTransitionProperties() throws Throwable { |
| enterScene(R.layout.scene1); |
| // Make the transition make changes to properties in getTransitionProperties. |
| TransitionPropertiesTransition transition = new TransitionPropertiesTransition(false); |
| mTransition = transition; |
| resetListener(); |
| startTransition(R.layout.scene2); |
| assertTrue(transition.latch.await(500, TimeUnit.MILLISECONDS)); |
| endTransition(); |
| |
| // Now make the transition only make changes to unimportant properties. |
| transition = new TransitionPropertiesTransition(true); |
| mTransition = transition; |
| resetListener(); |
| startTransition(R.layout.scene1); |
| verify(mListener, within(500)).onTransitionEnd(any()); |
| // createAnimator shouldn't have been called. |
| assertEquals(1, transition.latch.getCount()); |
| |
| assertNotNull(transition.getTransitionProperties()); |
| assertEquals(1, transition.getTransitionProperties().length); |
| } |
| |
| @Test |
| public void testGoWithNullParameter() throws Throwable { |
| final View layout1 = loadLayout(R.layout.scene1); |
| final Scene scene1 = loadScene(layout1); |
| |
| final View layout3 = loadLayout(R.layout.scene3); |
| final Scene scene3 = loadScene(layout3); |
| |
| enterScene(scene1); |
| |
| mActivityRule.runOnUiThread(() -> { |
| // scene1 |
| assertSame(layout1, mActivity.findViewById(R.id.holder)); |
| assertNotNull(mActivity.findViewById(R.id.hello)); |
| |
| TransitionManager.go(scene3, null); |
| // now at scene3 |
| assertSame(layout3, mActivity.findViewById(R.id.holder)); |
| assertNull(mActivity.findViewById(R.id.hello)); |
| |
| TransitionManager.go(scene1, null); |
| |
| // now at scene1 |
| assertSame(layout1, mActivity.findViewById(R.id.holder)); |
| assertNotNull(mActivity.findViewById(R.id.hello)); |
| }); |
| } |
| |
| private class NotRequiredTransition extends TestTransition { |
| @Override |
| public boolean isTransitionRequired(TransitionValues startValues, |
| TransitionValues newValues) { |
| return false; |
| } |
| } |
| |
| private class CaptureAnimatorTransition extends TestTransition { |
| public HashMap<View, Animator> animators = new HashMap<>(); |
| public HashMap<View, Animator.AnimatorListener> listeners = new HashMap<>(); |
| |
| @Override |
| public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues, |
| TransitionValues endValues) { |
| return setupAnimator(super.onAppear(sceneRoot, view, startValues, endValues), |
| endValues.view); |
| } |
| |
| @Override |
| public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues, |
| TransitionValues endValues) { |
| return setupAnimator(super.onDisappear(sceneRoot, view, startValues, endValues), |
| startValues.view); |
| } |
| |
| private Animator setupAnimator(Animator animator, View view) { |
| animators.put(view, animator); |
| Animator.AnimatorListener listener = mock(Animator.AnimatorListener.class); |
| animator.addListener(listener); |
| listeners.put(view, listener); |
| return animator; |
| } |
| } |
| |
| private class CheckTransitionValuesTransition extends TestTransition { |
| public CountDownLatch onAppearCalled = new CountDownLatch(1); |
| public CountDownLatch onDisappearCalled = new CountDownLatch(1); |
| @Override |
| public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues, |
| TransitionValues endValues) { |
| onAppearCalled.countDown(); |
| assertNull(getTransitionValues(endValues.view, true)); |
| assertEquals(endValues, getTransitionValues(endValues.view, false)); |
| return super.onAppear(sceneRoot, view, startValues, endValues); |
| } |
| |
| @Override |
| public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues, |
| TransitionValues endValues) { |
| onDisappearCalled.countDown(); |
| assertNull(getTransitionValues(startValues.view, false)); |
| assertEquals(startValues, getTransitionValues(startValues.view, true)); |
| return super.onDisappear(sceneRoot, view, startValues, endValues); |
| } |
| } |
| |
| private static class TransitionPropertiesTransition extends Transition { |
| private static final String SIDE_PROP = "prop1"; |
| private static final String IMPORTANT_PROP = "prop2"; |
| private static final String[] PROPERTIES = { |
| IMPORTANT_PROP |
| }; |
| |
| private boolean mOnlyUnimportant; |
| public CountDownLatch latch = new CountDownLatch(1); |
| |
| public TransitionPropertiesTransition(boolean onlyUnimportant) { |
| mOnlyUnimportant = onlyUnimportant; |
| } |
| |
| @Override |
| public String[] getTransitionProperties() { |
| return PROPERTIES; |
| } |
| |
| @Override |
| public void captureStartValues(TransitionValues transitionValues) { |
| transitionValues.values.put(SIDE_PROP, 1); |
| transitionValues.values.put(IMPORTANT_PROP, 1); |
| } |
| |
| @Override |
| public void captureEndValues(TransitionValues transitionValues) { |
| transitionValues.values.put(SIDE_PROP, 2); |
| int val = mOnlyUnimportant ? 1 : 2; |
| transitionValues.values.put(IMPORTANT_PROP, val); |
| } |
| |
| @Override |
| public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, |
| TransitionValues endValues) { |
| if (startValues != null && endValues != null) { |
| latch.countDown(); |
| } |
| |
| return null; |
| } |
| } |
| |
| private static class DurationListener extends TransitionListenerAdapter { |
| |
| private long mUptimeMillisStart = -1; |
| private long mDuration = -1; |
| |
| @Override |
| public void onTransitionStart(Transition transition) { |
| mUptimeMillisStart = SystemClock.uptimeMillis(); |
| } |
| |
| @Override |
| public void onTransitionEnd(Transition transition) { |
| mDuration = SystemClock.uptimeMillis() - mUptimeMillisStart; |
| } |
| |
| public long getDuration() { |
| if (mDuration < 0) { |
| fail("Requested duration measurement of an incomplete transition."); |
| } |
| return mDuration; |
| } |
| } |
| } |