summaryrefslogtreecommitdiffstats
path: root/core/java/android/transition/SidePropagation.java
diff options
context:
space:
mode:
authorGeorge Mount <mount@google.com>2014-03-10 16:51:16 -0700
committerGeorge Mount <mount@google.com>2014-04-07 09:14:09 -0700
commitd6107a3170df61d9e776fcd5666acfc9135c6f16 (patch)
tree8eebc42794fe87d3974a3e9bd21ab47b0244ae23 /core/java/android/transition/SidePropagation.java
parentcb4b7d999e7bcba608726188421772e313e67163 (diff)
downloadframeworks_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.java165
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();
+ }
+ }
+}