diff options
| author | George Mount <mount@google.com> | 2014-03-10 16:51:16 -0700 |
|---|---|---|
| committer | George Mount <mount@google.com> | 2014-04-07 09:14:09 -0700 |
| commit | d6107a3170df61d9e776fcd5666acfc9135c6f16 (patch) | |
| tree | 8eebc42794fe87d3974a3e9bd21ab47b0244ae23 /core/java/android/transition/SidePropagation.java | |
| parent | cb4b7d999e7bcba608726188421772e313e67163 (diff) | |
| download | frameworks_base-d6107a3170df61d9e776fcd5666acfc9135c6f16.zip frameworks_base-d6107a3170df61d9e776fcd5666acfc9135c6f16.tar.gz frameworks_base-d6107a3170df61d9e776fcd5666acfc9135c6f16.tar.bz2 | |
Add Transitions useful for Activity transitions.
Slide: transition in and out of the edge of the scene.
Explode: transition to the scene borders
Moved capability from Fade to Visibility.
Change-Id: Ibeb0d8f751c990edc467570d9665fbe251af2703
Diffstat (limited to 'core/java/android/transition/SidePropagation.java')
| -rw-r--r-- | core/java/android/transition/SidePropagation.java | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/core/java/android/transition/SidePropagation.java b/core/java/android/transition/SidePropagation.java new file mode 100644 index 0000000..c331945 --- /dev/null +++ b/core/java/android/transition/SidePropagation.java @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2014 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.graphics.Rect; +import android.util.FloatMath; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; + +/** + * A <code>TransitionPropagation</code> that propagates based on the distance to the side + * and, orthogonally, the distance to epicenter. If the transitioning View is visible in + * the start of the transition, then it will transition sooner when closer to the side and + * later when farther. If the view is not visible in the start of the transition, then + * it will transition later when closer to the side and sooner when farther from the edge. + * This is the default TransitionPropagation used with {@link android.transition.Slide}. + */ +public class SidePropagation extends VisibilityPropagation { + private static final String TAG = "SlidePropagation"; + + /** + * Transition propagates relative to the distance of the left side of the scene. + */ + public static final int LEFT = Slide.LEFT; + + /** + * Transition propagates relative to the distance of the top of the scene. + */ + public static final int TOP = Slide.TOP; + + /** + * Transition propagates relative to the distance of the right side of the scene. + */ + public static final int RIGHT = Slide.RIGHT; + + /** + * Transition propagates relative to the distance of the bottom of the scene. + */ + public static final int BOTTOM = Slide.BOTTOM; + + private float mPropagationSpeed = 4.0f; + private int mSide = BOTTOM; + + /** + * Sets the side that is used to calculate the transition propagation. If the transitioning + * View is visible in the start of the transition, then it will transition sooner when + * closer to the side and later when farther. If the view is not visible in the start of + * the transition, then it will transition later when closer to the side and sooner when + * farther from the edge. The default is {@link #BOTTOM}. + * + * @param side The side that is used to calculate the transition propagation. Must be one of + * {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, or {@link #BOTTOM}. + */ + public void setSide(int side) { + mSide = side; + } + + /** + * Sets the speed at which transition propagation happens, relative to the duration of the + * Transition. A <code>propagationSpeed</code> of 1 means that a View centered at the side + * set in {@link #setSide(int)} and View centered at the opposite edge will have a difference + * in start delay of approximately the duration of the Transition. A speed of 2 means the + * start delay difference will be approximately half of the duration of the transition. A + * value of 0 is illegal, but negative values will invert the propagation. + * + * @param propagationSpeed The speed at which propagation occurs, relative to the duration + * of the transition. A speed of 4 means it works 4 times as fast + * as the duration of the transition. May not be 0. + */ + public void setPropagationSpeed(float propagationSpeed) { + if (propagationSpeed == 0) { + throw new IllegalArgumentException("propagationSpeed may not be 0"); + } + mPropagationSpeed = propagationSpeed; + } + + @Override + public long getStartDelay(ViewGroup sceneRoot, Transition transition, + TransitionValues startValues, TransitionValues endValues) { + if (startValues == null && endValues == null) { + return 0; + } + int directionMultiplier = 1; + Rect epicenter = transition.getEpicenter(); + TransitionValues positionValues; + if (endValues == null || getViewVisibility(startValues) == View.VISIBLE) { + positionValues = startValues; + directionMultiplier = -1; + } else { + positionValues = endValues; + } + + int viewCenterX = getViewX(positionValues); + int viewCenterY = getViewY(positionValues); + + int[] loc = new int[2]; + sceneRoot.getLocationOnScreen(loc); + int left = loc[0] + Math.round(sceneRoot.getTranslationX()); + int top = loc[1] + Math.round(sceneRoot.getTranslationY()); + int right = left + sceneRoot.getWidth(); + int bottom = top + sceneRoot.getHeight(); + + int epicenterX; + int epicenterY; + if (epicenter != null) { + epicenterX = epicenter.centerX(); + epicenterY = epicenter.centerY(); + } else { + epicenterX = (left + right) / 2; + epicenterY = (top + bottom) / 2; + } + + float distance = distance(viewCenterX, viewCenterY, epicenterX, epicenterY, + left, top, right, bottom); + float maxDistance = getMaxDistance(sceneRoot); + float distanceFraction = distance/maxDistance; + + return Math.round(transition.getDuration() * directionMultiplier / mPropagationSpeed + * distanceFraction); + } + + private int distance(int viewX, int viewY, int epicenterX, int epicenterY, + int left, int top, int right, int bottom) { + int distance = 0; + switch (mSide) { + case LEFT: + distance = right - viewX + Math.abs(epicenterY - viewY); + break; + case TOP: + distance = bottom - viewY + Math.abs(epicenterX - viewX); + break; + case RIGHT: + distance = viewX - left + Math.abs(epicenterY - viewY); + break; + case BOTTOM: + distance = viewY - top + Math.abs(epicenterX - viewX); + break; + } + return distance; + } + + private int getMaxDistance(ViewGroup sceneRoot) { + switch (mSide) { + case LEFT: + case RIGHT: + return sceneRoot.getWidth(); + default: + return sceneRoot.getHeight(); + } + } +} |
