summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/transition/Slide.java50
-rw-r--r--core/tests/coretests/src/android/transition/SlideTransitionTest.java174
2 files changed, 202 insertions, 22 deletions
diff --git a/core/java/android/transition/Slide.java b/core/java/android/transition/Slide.java
index 9af65e403679..2645f861a5ad 100644
--- a/core/java/android/transition/Slide.java
+++ b/core/java/android/transition/Slide.java
@@ -47,6 +47,7 @@ public class Slide extends Visibility {
private static final String PROPNAME_SCREEN_POSITION = "android:slide:screenPosition";
private CalculateSlide mSlideCalculator = sCalculateBottom;
private @GravityFlag int mSlideEdge = Gravity.BOTTOM;
+ private float mSlideFraction = 1;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -56,16 +57,16 @@ public class Slide extends Visibility {
private interface CalculateSlide {
/** Returns the translation value for view when it goes out of the scene */
- float getGoneX(ViewGroup sceneRoot, View view);
+ float getGoneX(ViewGroup sceneRoot, View view, float fraction);
/** Returns the translation value for view when it goes out of the scene */
- float getGoneY(ViewGroup sceneRoot, View view);
+ float getGoneY(ViewGroup sceneRoot, View view, float fraction);
}
private static abstract class CalculateSlideHorizontal implements CalculateSlide {
@Override
- public float getGoneY(ViewGroup sceneRoot, View view) {
+ public float getGoneY(ViewGroup sceneRoot, View view, float fraction) {
return view.getTranslationY();
}
}
@@ -73,27 +74,27 @@ public class Slide extends Visibility {
private static abstract class CalculateSlideVertical implements CalculateSlide {
@Override
- public float getGoneX(ViewGroup sceneRoot, View view) {
+ public float getGoneX(ViewGroup sceneRoot, View view, float fraction) {
return view.getTranslationX();
}
}
private static final CalculateSlide sCalculateLeft = new CalculateSlideHorizontal() {
@Override
- public float getGoneX(ViewGroup sceneRoot, View view) {
- return view.getTranslationX() - sceneRoot.getWidth();
+ public float getGoneX(ViewGroup sceneRoot, View view, float fraction) {
+ return view.getTranslationX() - sceneRoot.getWidth() * fraction;
}
};
private static final CalculateSlide sCalculateStart = new CalculateSlideHorizontal() {
@Override
- public float getGoneX(ViewGroup sceneRoot, View view) {
+ public float getGoneX(ViewGroup sceneRoot, View view, float fraction) {
final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
final float x;
if (isRtl) {
- x = view.getTranslationX() + sceneRoot.getWidth();
+ x = view.getTranslationX() + sceneRoot.getWidth() * fraction;
} else {
- x = view.getTranslationX() - sceneRoot.getWidth();
+ x = view.getTranslationX() - sceneRoot.getWidth() * fraction;
}
return x;
}
@@ -101,27 +102,27 @@ public class Slide extends Visibility {
private static final CalculateSlide sCalculateTop = new CalculateSlideVertical() {
@Override
- public float getGoneY(ViewGroup sceneRoot, View view) {
- return view.getTranslationY() - sceneRoot.getHeight();
+ public float getGoneY(ViewGroup sceneRoot, View view, float fraction) {
+ return view.getTranslationY() - sceneRoot.getHeight() * fraction;
}
};
private static final CalculateSlide sCalculateRight = new CalculateSlideHorizontal() {
@Override
- public float getGoneX(ViewGroup sceneRoot, View view) {
- return view.getTranslationX() + sceneRoot.getWidth();
+ public float getGoneX(ViewGroup sceneRoot, View view, float fraction) {
+ return view.getTranslationX() + sceneRoot.getWidth() * fraction;
}
};
private static final CalculateSlide sCalculateEnd = new CalculateSlideHorizontal() {
@Override
- public float getGoneX(ViewGroup sceneRoot, View view) {
+ public float getGoneX(ViewGroup sceneRoot, View view, float fraction) {
final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
final float x;
if (isRtl) {
- x = view.getTranslationX() - sceneRoot.getWidth();
+ x = view.getTranslationX() - sceneRoot.getWidth() * fraction;
} else {
- x = view.getTranslationX() + sceneRoot.getWidth();
+ x = view.getTranslationX() + sceneRoot.getWidth() * fraction;
}
return x;
}
@@ -129,8 +130,8 @@ public class Slide extends Visibility {
private static final CalculateSlide sCalculateBottom = new CalculateSlideVertical() {
@Override
- public float getGoneY(ViewGroup sceneRoot, View view) {
- return view.getTranslationY() + sceneRoot.getHeight();
+ public float getGoneY(ViewGroup sceneRoot, View view, float fraction) {
+ return view.getTranslationY() + sceneRoot.getHeight() * fraction;
}
};
@@ -237,8 +238,8 @@ public class Slide extends Visibility {
int[] position = (int[]) endValues.values.get(PROPNAME_SCREEN_POSITION);
float endX = view.getTranslationX();
float endY = view.getTranslationY();
- float startX = mSlideCalculator.getGoneX(sceneRoot, view);
- float startY = mSlideCalculator.getGoneY(sceneRoot, view);
+ float startX = mSlideCalculator.getGoneX(sceneRoot, view, mSlideFraction);
+ float startY = mSlideCalculator.getGoneY(sceneRoot, view, mSlideFraction);
return TranslationAnimationCreator
.createAnimation(view, endValues, position[0], position[1],
startX, startY, endX, endY, sDecelerate, this);
@@ -253,10 +254,15 @@ public class Slide extends Visibility {
int[] position = (int[]) startValues.values.get(PROPNAME_SCREEN_POSITION);
float startX = view.getTranslationX();
float startY = view.getTranslationY();
- float endX = mSlideCalculator.getGoneX(sceneRoot, view);
- float endY = mSlideCalculator.getGoneY(sceneRoot, view);
+ float endX = mSlideCalculator.getGoneX(sceneRoot, view, mSlideFraction);
+ float endY = mSlideCalculator.getGoneY(sceneRoot, view, mSlideFraction);
return TranslationAnimationCreator
.createAnimation(view, startValues, position[0], position[1],
startX, startY, endX, endY, sAccelerate, this);
}
+
+ /** @hide */
+ public void setSlideFraction(float slideFraction) {
+ mSlideFraction = slideFraction;
+ }
}
diff --git a/core/tests/coretests/src/android/transition/SlideTransitionTest.java b/core/tests/coretests/src/android/transition/SlideTransitionTest.java
new file mode 100644
index 000000000000..8b9ec74be8df
--- /dev/null
+++ b/core/tests/coretests/src/android/transition/SlideTransitionTest.java
@@ -0,0 +1,174 @@
+/*
+ * 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 android.transition;
+
+import android.animation.AnimatorSetActivity;
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+
+import com.android.frameworks.coretests.R;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+
+public class SlideTransitionTest extends ActivityInstrumentationTestCase2<AnimatorSetActivity> {
+
+ Activity mActivity;
+
+ public SlideTransitionTest() {
+ super(AnimatorSetActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ mActivity = getActivity();
+ }
+
+ @SmallTest
+ public void testShortSlide() throws Throwable {
+ final float slideFraction = 0.5f;
+ final View square1 = mActivity.findViewById(R.id.square1);
+ final View sceneRoot = mActivity.findViewById(R.id.container);
+ final SlideTranslationValueRatchet ratchet = new SlideTranslationValueRatchet(square1);
+ square1.getViewTreeObserver().addOnPreDrawListener(ratchet);
+
+ final Slide slideOut = new Slide(Gravity.BOTTOM);
+ final float finalOffsetOut = sceneRoot.getHeight() * slideFraction;
+ slideOut.setSlideFraction(slideFraction);
+ TransitionLatch latch = setVisibilityInTransition(slideOut, R.id.square1, View.INVISIBLE);
+ assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
+ assertEquals(0f, square1.getTranslationY(), 0.1f);
+ assertEquals(View.VISIBLE, square1.getVisibility());
+ Thread.sleep(100);
+ assertFalse(square1.getTranslationY() < 0.1
+ || square1.getTranslationY() > finalOffsetOut - 0.1);
+ assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
+ // Give this 20% slop in case some frames get dropped.
+ assertTrue(finalOffsetOut * 0.8 < ratchet.maxY);
+ assertTrue(finalOffsetOut + 0.1 > ratchet.maxY);
+ assertEquals(View.INVISIBLE, square1.getVisibility());
+
+ ratchet.reset();
+ final Slide slideIn = new Slide(Gravity.BOTTOM);
+ final float initialOffsetIn = sceneRoot.getHeight() * slideFraction;
+ slideIn.setSlideFraction(slideFraction);
+ latch = setVisibilityInTransition(slideIn, R.id.square1, View.VISIBLE);
+ assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
+ assertEquals(initialOffsetIn, square1.getTranslationY(), 0.1f);
+ assertEquals(View.VISIBLE, square1.getVisibility());
+ Thread.sleep(100);
+ assertFalse(square1.getTranslationY() < 0.1
+ || square1.getTranslationY() > initialOffsetIn - 0.1);
+ assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
+ assertEquals(0f, ratchet.minY, 0.1);
+ assertEquals(0f, square1.getTranslationY(), 0.1);
+ assertEquals(View.VISIBLE, square1.getVisibility());
+
+ square1.getViewTreeObserver().removeOnPreDrawListener(ratchet);
+ }
+
+ public TransitionLatch setVisibilityInTransition(final Transition transition, int viewId,
+ final int visibility) throws Throwable {
+ final ViewGroup sceneRoot = (ViewGroup) mActivity.findViewById(R.id.container);
+ final View view = sceneRoot.findViewById(viewId);
+ TransitionLatch latch = new TransitionLatch();
+ transition.addListener(latch);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ TransitionManager.beginDelayedTransition(sceneRoot, transition);
+ view.setVisibility(visibility);
+ }
+ });
+ return latch;
+ }
+
+ public static class TransitionLatch implements Transition.TransitionListener {
+ public CountDownLatch startLatch = new CountDownLatch(1);
+ public CountDownLatch endLatch = new CountDownLatch(1);
+ public CountDownLatch cancelLatch = new CountDownLatch(1);
+ public CountDownLatch pauseLatch = new CountDownLatch(1);
+ public CountDownLatch resumeLatch = new CountDownLatch(1);
+
+ @Override
+ public void onTransitionStart(Transition transition) {
+ startLatch.countDown();
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ endLatch.countDown();
+ transition.removeListener(this);
+ }
+
+ @Override
+ public void onTransitionCancel(Transition transition) {
+ cancelLatch.countDown();
+ }
+
+ @Override
+ public void onTransitionPause(Transition transition) {
+ pauseLatch.countDown();
+ }
+
+ @Override
+ public void onTransitionResume(Transition transition) {
+ resumeLatch.countDown();
+ }
+ }
+
+ private static class SlideTranslationValueRatchet
+ implements ViewTreeObserver.OnPreDrawListener {
+
+ private final View mView;
+ private boolean mInitialized;
+ public float minX = Float.NaN;
+ public float minY = Float.NaN;
+ public float maxX = Float.NaN;
+ public float maxY = Float.NaN;
+
+ public SlideTranslationValueRatchet(View view) {
+ mView = view;
+ }
+
+ public void reset() {
+ minX = minY = maxX = maxY = Float.NaN;
+ mInitialized = false;
+ }
+
+ @Override
+ public boolean onPreDraw() {
+ if (!mInitialized) {
+ minX = maxX = mView.getTranslationX();
+ minY = maxY = mView.getTranslationY();
+ mInitialized = true;
+ } else {
+ minX = Math.min(minX, mView.getTranslationX());
+ minY = Math.min(minY, mView.getTranslationY());
+ maxX = Math.max(maxX, mView.getTranslationX());
+ maxY = Math.max(maxY, mView.getTranslationY());
+ }
+ return true;
+ }
+ }
+}