Slide.java revision 1f8c01181bcdef6e7e7e359ecde003939523b718
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package android.transition; 17 18import android.animation.Animator; 19import android.animation.TimeInterpolator; 20import android.view.Gravity; 21import android.view.View; 22import android.view.ViewGroup; 23import android.view.animation.AccelerateInterpolator; 24import android.view.animation.DecelerateInterpolator; 25 26/** 27 * This transition tracks changes to the visibility of target views in the 28 * start and end scenes and moves views in or out from one of the edges of the 29 * scene. Visibility is determined by both the 30 * {@link View#setVisibility(int)} state of the view as well as whether it 31 * is parented in the current view hierarchy. Disappearing Views are 32 * limited as described in {@link Visibility#onDisappear(android.view.ViewGroup, 33 * TransitionValues, int, TransitionValues, int)}. 34 */ 35public class Slide extends Visibility { 36 private static final String TAG = "Slide"; 37 private static final TimeInterpolator sDecelerate = new DecelerateInterpolator(); 38 private static final TimeInterpolator sAccelerate = new AccelerateInterpolator(); 39 private static final String PROPNAME_SCREEN_POSITION = "android:slide:screenPosition"; 40 private CalculateSlide mSlideCalculator = sCalculateBottom; 41 42 private interface CalculateSlide { 43 44 /** Returns the translation value for view when it goes out of the scene */ 45 float getGoneX(ViewGroup sceneRoot, View view); 46 47 /** Returns the translation value for view when it goes out of the scene */ 48 float getGoneY(ViewGroup sceneRoot, View view); 49 } 50 51 private static abstract class CalculateSlideHorizontal implements CalculateSlide { 52 53 @Override 54 public float getGoneY(ViewGroup sceneRoot, View view) { 55 return view.getTranslationY(); 56 } 57 } 58 59 private static abstract class CalculateSlideVertical implements CalculateSlide { 60 61 @Override 62 public float getGoneX(ViewGroup sceneRoot, View view) { 63 return view.getTranslationX(); 64 } 65 } 66 67 private static final CalculateSlide sCalculateLeft = new CalculateSlideHorizontal() { 68 @Override 69 public float getGoneX(ViewGroup sceneRoot, View view) { 70 return view.getTranslationX() - sceneRoot.getWidth(); 71 } 72 }; 73 74 private static final CalculateSlide sCalculateTop = new CalculateSlideVertical() { 75 @Override 76 public float getGoneY(ViewGroup sceneRoot, View view) { 77 return view.getTranslationY() - sceneRoot.getHeight(); 78 } 79 }; 80 81 private static final CalculateSlide sCalculateRight = new CalculateSlideHorizontal() { 82 @Override 83 public float getGoneX(ViewGroup sceneRoot, View view) { 84 return view.getTranslationX() + sceneRoot.getWidth(); 85 } 86 }; 87 88 private static final CalculateSlide sCalculateBottom = new CalculateSlideVertical() { 89 @Override 90 public float getGoneY(ViewGroup sceneRoot, View view) { 91 return view.getTranslationY() + sceneRoot.getHeight(); 92 } 93 }; 94 95 /** 96 * Constructor using the default {@link Gravity#BOTTOM} 97 * slide edge direction. 98 */ 99 public Slide() { 100 setSlideEdge(Gravity.BOTTOM); 101 } 102 103 /** 104 * Constructor using the provided slide edge direction. 105 */ 106 public Slide(int slideEdge) { 107 setSlideEdge(slideEdge); 108 } 109 110 private void captureValues(TransitionValues transitionValues) { 111 View view = transitionValues.view; 112 int[] position = new int[2]; 113 view.getLocationOnScreen(position); 114 transitionValues.values.put(PROPNAME_SCREEN_POSITION, position); 115 } 116 117 @Override 118 public void captureStartValues(TransitionValues transitionValues) { 119 super.captureStartValues(transitionValues); 120 captureValues(transitionValues); 121 } 122 123 @Override 124 public void captureEndValues(TransitionValues transitionValues) { 125 super.captureEndValues(transitionValues); 126 captureValues(transitionValues); 127 } 128 129 /** 130 * Change the edge that Views appear and disappear from. 131 * 132 * @param slideEdge The edge of the scene to use for Views appearing and disappearing. One of 133 * {@link android.view.Gravity#LEFT}, {@link android.view.Gravity#TOP}, 134 * {@link android.view.Gravity#RIGHT}, {@link android.view.Gravity#BOTTOM}. 135 */ 136 public void setSlideEdge(int slideEdge) { 137 switch (slideEdge) { 138 case Gravity.LEFT: 139 mSlideCalculator = sCalculateLeft; 140 break; 141 case Gravity.TOP: 142 mSlideCalculator = sCalculateTop; 143 break; 144 case Gravity.RIGHT: 145 mSlideCalculator = sCalculateRight; 146 break; 147 case Gravity.BOTTOM: 148 mSlideCalculator = sCalculateBottom; 149 break; 150 default: 151 throw new IllegalArgumentException("Invalid slide direction"); 152 } 153 SidePropagation propagation = new SidePropagation(); 154 propagation.setSide(slideEdge); 155 setPropagation(propagation); 156 } 157 158 @Override 159 public Animator onAppear(ViewGroup sceneRoot, View view, 160 TransitionValues startValues, TransitionValues endValues) { 161 if (endValues == null) { 162 return null; 163 } 164 int[] position = (int[]) endValues.values.get(PROPNAME_SCREEN_POSITION); 165 float endX = view.getTranslationX(); 166 float endY = view.getTranslationY(); 167 float startX = mSlideCalculator.getGoneX(sceneRoot, view); 168 float startY = mSlideCalculator.getGoneY(sceneRoot, view); 169 return TranslationAnimationCreator 170 .createAnimation(view, endValues, position[0], position[1], 171 startX, startY, endX, endY, sDecelerate); 172 } 173 174 @Override 175 public Animator onDisappear(ViewGroup sceneRoot, View view, 176 TransitionValues startValues, TransitionValues endValues) { 177 if (startValues == null) { 178 return null; 179 } 180 int[] position = (int[]) startValues.values.get(PROPNAME_SCREEN_POSITION); 181 float startX = view.getTranslationX(); 182 float startY = view.getTranslationY(); 183 float endX = mSlideCalculator.getGoneX(sceneRoot, view); 184 float endY = mSlideCalculator.getGoneY(sceneRoot, view); 185 return TranslationAnimationCreator 186 .createAnimation(view, startValues, position[0], position[1], 187 startX, startY, endX, endY, sAccelerate); 188 } 189} 190