diff --git a/core/java/android/transition/SidePropagation.java b/core/java/android/transition/SidePropagation.java index 623cdd18ee44e..ad6c2dd41a950 100644 --- a/core/java/android/transition/SidePropagation.java +++ b/core/java/android/transition/SidePropagation.java @@ -44,8 +44,8 @@ public class SidePropagation extends VisibilityPropagation { * farther from the edge. The default is {@link Gravity#BOTTOM}. * * @param side The side that is used to calculate the transition propagation. Must be one of - * {@link Gravity#LEFT}, {@link Gravity#TOP}, {@link Gravity#RIGHT}, or - * {@link Gravity#BOTTOM}. + * {@link Gravity#LEFT}, {@link Gravity#TOP}, {@link Gravity#RIGHT}, + * {@link Gravity#BOTTOM}, {@link Gravity#START}, or {@link Gravity#END}. */ public void setSide(int side) { mSide = side; @@ -106,7 +106,7 @@ public class SidePropagation extends VisibilityPropagation { epicenterY = (top + bottom) / 2; } - float distance = distance(viewCenterX, viewCenterY, epicenterX, epicenterY, + float distance = distance(sceneRoot, viewCenterX, viewCenterY, epicenterX, epicenterY, left, top, right, bottom); float maxDistance = getMaxDistance(sceneRoot); float distanceFraction = distance/maxDistance; @@ -119,10 +119,20 @@ public class SidePropagation extends VisibilityPropagation { return Math.round(duration * directionMultiplier / mPropagationSpeed * distanceFraction); } - private int distance(int viewX, int viewY, int epicenterX, int epicenterY, + private int distance(View sceneRoot, int viewX, int viewY, int epicenterX, int epicenterY, int left, int top, int right, int bottom) { + final int side; + if (mSide == Gravity.START) { + final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; + side = isRtl ? Gravity.RIGHT : Gravity.LEFT; + } else if (mSide == Gravity.END) { + final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; + side = isRtl ? Gravity.LEFT : Gravity.RIGHT; + } else { + side = mSide; + } int distance = 0; - switch (mSide) { + switch (side) { case Gravity.LEFT: distance = right - viewX + Math.abs(epicenterY - viewY); break; @@ -143,6 +153,8 @@ public class SidePropagation extends VisibilityPropagation { switch (mSide) { case Gravity.LEFT: case Gravity.RIGHT: + case Gravity.START: + case Gravity.END: return sceneRoot.getWidth(); default: return sceneRoot.getHeight(); diff --git a/core/java/android/transition/Slide.java b/core/java/android/transition/Slide.java index ae2e4aaec35be..be1d9070c808b 100644 --- a/core/java/android/transition/Slide.java +++ b/core/java/android/transition/Slide.java @@ -76,6 +76,20 @@ public class Slide extends Visibility { } }; + private static final CalculateSlide sCalculateStart = new CalculateSlideHorizontal() { + @Override + public float getGoneX(ViewGroup sceneRoot, View view) { + final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; + final float x; + if (isRtl) { + x = view.getTranslationX() + sceneRoot.getWidth(); + } else { + x = view.getTranslationX() - sceneRoot.getWidth(); + } + return x; + } + }; + private static final CalculateSlide sCalculateTop = new CalculateSlideVertical() { @Override public float getGoneY(ViewGroup sceneRoot, View view) { @@ -90,6 +104,20 @@ public class Slide extends Visibility { } }; + private static final CalculateSlide sCalculateEnd = new CalculateSlideHorizontal() { + @Override + public float getGoneX(ViewGroup sceneRoot, View view) { + final boolean isRtl = sceneRoot.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; + final float x; + if (isRtl) { + x = view.getTranslationX() - sceneRoot.getWidth(); + } else { + x = view.getTranslationX() + sceneRoot.getWidth(); + } + return x; + } + }; + private static final CalculateSlide sCalculateBottom = new CalculateSlideVertical() { @Override public float getGoneY(ViewGroup sceneRoot, View view) { @@ -144,7 +172,8 @@ public class Slide extends Visibility { * * @param slideEdge The edge of the scene to use for Views appearing and disappearing. One of * {@link android.view.Gravity#LEFT}, {@link android.view.Gravity#TOP}, - * {@link android.view.Gravity#RIGHT}, {@link android.view.Gravity#BOTTOM}. + * {@link android.view.Gravity#RIGHT}, {@link android.view.Gravity#BOTTOM}, + * {@link android.view.Gravity#START}, {@link android.view.Gravity#END}. * @attr ref android.R.styleable#Slide_slideEdge */ public void setSlideEdge(int slideEdge) { @@ -161,6 +190,12 @@ public class Slide extends Visibility { case Gravity.BOTTOM: mSlideCalculator = sCalculateBottom; break; + case Gravity.START: + mSlideCalculator = sCalculateStart; + break; + case Gravity.END: + mSlideCalculator = sCalculateEnd; + break; default: throw new IllegalArgumentException("Invalid slide direction"); } @@ -175,7 +210,8 @@ public class Slide extends Visibility { * * @return the edge of the scene to use for Views appearing and disappearing. One of * {@link android.view.Gravity#LEFT}, {@link android.view.Gravity#TOP}, - * {@link android.view.Gravity#RIGHT}, {@link android.view.Gravity#BOTTOM}. + * {@link android.view.Gravity#RIGHT}, {@link android.view.Gravity#BOTTOM}, + * {@link android.view.Gravity#START}, {@link android.view.Gravity#END}. * @attr ref android.R.styleable#Slide_slideEdge */ public int getSlideEdge() { diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 403fd990e9ec2..2fd7d3091a9bc 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -5665,6 +5665,10 @@ + + + +