1 /*
2  * Copyright (C) 2006 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  */
16 
17 package android.view.animation;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.content.Context;
21 import android.content.res.TypedArray;
22 import android.util.AttributeSet;
23 
24 /**
25  * An animation that controls the position of an object. See the
26  * {@link android.view.animation full package} description for details and
27  * sample code.
28  *
29  */
30 public class TranslateAnimation extends Animation {
31     private int mFromXType = ABSOLUTE;
32     private int mToXType = ABSOLUTE;
33 
34     private int mFromYType = ABSOLUTE;
35     private int mToYType = ABSOLUTE;
36 
37     /** @hide */
38     @UnsupportedAppUsage
39     protected float mFromXValue = 0.0f;
40     /** @hide */
41     @UnsupportedAppUsage
42     protected float mToXValue = 0.0f;
43 
44     /** @hide */
45     @UnsupportedAppUsage
46     protected float mFromYValue = 0.0f;
47     /** @hide */
48     @UnsupportedAppUsage
49     protected float mToYValue = 0.0f;
50 
51     /** @hide */
52     protected float mFromXDelta;
53     /** @hide */
54     protected float mToXDelta;
55     /** @hide */
56     protected float mFromYDelta;
57     /** @hide */
58     protected float mToYDelta;
59 
60     private int mWidth;
61     private int mParentWidth;
62 
63     /**
64      * Constructor used when a TranslateAnimation is loaded from a resource.
65      *
66      * @param context Application context to use
67      * @param attrs Attribute set from which to read values
68      */
TranslateAnimation(Context context, AttributeSet attrs)69     public TranslateAnimation(Context context, AttributeSet attrs) {
70         super(context, attrs);
71 
72         TypedArray a = context.obtainStyledAttributes(attrs,
73                 com.android.internal.R.styleable.TranslateAnimation);
74 
75         Description d = Description.parseValue(a.peekValue(
76                 com.android.internal.R.styleable.TranslateAnimation_fromXDelta), context);
77         mFromXType = d.type;
78         mFromXValue = d.value;
79 
80         d = Description.parseValue(a.peekValue(
81                 com.android.internal.R.styleable.TranslateAnimation_toXDelta), context);
82         mToXType = d.type;
83         mToXValue = d.value;
84 
85         d = Description.parseValue(a.peekValue(
86                 com.android.internal.R.styleable.TranslateAnimation_fromYDelta), context);
87         mFromYType = d.type;
88         mFromYValue = d.value;
89 
90         d = Description.parseValue(a.peekValue(
91                 com.android.internal.R.styleable.TranslateAnimation_toYDelta), context);
92         mToYType = d.type;
93         mToYValue = d.value;
94 
95         a.recycle();
96     }
97 
98     /**
99      * Constructor to use when building a TranslateAnimation from code
100      *
101      * @param fromXDelta Change in X coordinate to apply at the start of the
102      *        animation
103      * @param toXDelta Change in X coordinate to apply at the end of the
104      *        animation
105      * @param fromYDelta Change in Y coordinate to apply at the start of the
106      *        animation
107      * @param toYDelta Change in Y coordinate to apply at the end of the
108      *        animation
109      */
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)110     public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
111         mFromXValue = fromXDelta;
112         mToXValue = toXDelta;
113         mFromYValue = fromYDelta;
114         mToYValue = toYDelta;
115 
116         mFromXType = ABSOLUTE;
117         mToXType = ABSOLUTE;
118         mFromYType = ABSOLUTE;
119         mToYType = ABSOLUTE;
120     }
121 
122     /**
123      * Constructor to use when building a TranslateAnimation from code
124      *
125      * @param fromXType Specifies how fromXValue should be interpreted. One of
126      *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
127      *        Animation.RELATIVE_TO_PARENT.
128      * @param fromXValue Change in X coordinate to apply at the start of the
129      *        animation. This value can either be an absolute number if fromXType
130      *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
131      * @param toXType Specifies how toXValue should be interpreted. One of
132      *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
133      *        Animation.RELATIVE_TO_PARENT.
134      * @param toXValue Change in X coordinate to apply at the end of the
135      *        animation. This value can either be an absolute number if toXType
136      *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
137      * @param fromYType Specifies how fromYValue should be interpreted. One of
138      *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
139      *        Animation.RELATIVE_TO_PARENT.
140      * @param fromYValue Change in Y coordinate to apply at the start of the
141      *        animation. This value can either be an absolute number if fromYType
142      *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
143      * @param toYType Specifies how toYValue should be interpreted. One of
144      *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
145      *        Animation.RELATIVE_TO_PARENT.
146      * @param toYValue Change in Y coordinate to apply at the end of the
147      *        animation. This value can either be an absolute number if toYType
148      *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
149      */
TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue)150     public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
151             int fromYType, float fromYValue, int toYType, float toYValue) {
152 
153         mFromXValue = fromXValue;
154         mToXValue = toXValue;
155         mFromYValue = fromYValue;
156         mToYValue = toYValue;
157 
158         mFromXType = fromXType;
159         mToXType = toXType;
160         mFromYType = fromYType;
161         mToYType = toYType;
162     }
163 
164 
165     @Override
applyTransformation(float interpolatedTime, Transformation t)166     protected void applyTransformation(float interpolatedTime, Transformation t) {
167         float dx = mFromXDelta;
168         float dy = mFromYDelta;
169         if (mFromXDelta != mToXDelta) {
170             dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
171         }
172         if (mFromYDelta != mToYDelta) {
173             dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
174         }
175         t.getMatrix().setTranslate(dx, dy);
176     }
177 
178     @Override
initialize(int width, int height, int parentWidth, int parentHeight)179     public void initialize(int width, int height, int parentWidth, int parentHeight) {
180         super.initialize(width, height, parentWidth, parentHeight);
181         mFromXDelta = resolveSize(mFromXType, mFromXValue, width, parentWidth);
182         mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth);
183         mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight);
184         mToYDelta = resolveSize(mToYType, mToYValue, height, parentHeight);
185 
186         mWidth = width;
187         mParentWidth = parentWidth;
188     }
189 
190     /**
191      * Checks whether or not the translation is exclusively an x axis translation.
192      *
193      * @hide
194      */
isXAxisTransition()195     public boolean isXAxisTransition() {
196         return mFromXDelta - mToXDelta != 0 && mFromYDelta - mToYDelta == 0;
197     }
198 
199     /**
200      * Checks whether or not the translation is a full width x axis slide in or out translation.
201      *
202      * @hide
203      */
isFullWidthTranslate()204     public boolean isFullWidthTranslate() {
205         boolean isXAxisSlideTransition =
206                 isSlideInLeft() || isSlideOutRight() || isSlideInRight() || isSlideOutLeft();
207         return mWidth == mParentWidth && isXAxisSlideTransition;
208     }
209 
isSlideInLeft()210     private boolean isSlideInLeft() {
211         boolean startsOutOfParentOnLeft = mFromXDelta <= -mWidth;
212         return startsOutOfParentOnLeft && endsXEnclosedWithinParent();
213     }
214 
isSlideOutRight()215     private boolean isSlideOutRight() {
216         boolean endOutOfParentOnRight = mToXDelta >= mParentWidth;
217         return startsXEnclosedWithinParent() && endOutOfParentOnRight;
218     }
219 
isSlideInRight()220     private boolean isSlideInRight() {
221         boolean startsOutOfParentOnRight = mFromXDelta >= mParentWidth;
222         return startsOutOfParentOnRight && endsXEnclosedWithinParent();
223     }
224 
isSlideOutLeft()225     private boolean isSlideOutLeft() {
226         boolean endOutOfParentOnLeft = mToXDelta <= -mWidth;
227         return startsXEnclosedWithinParent() && endOutOfParentOnLeft;
228     }
229 
endsXEnclosedWithinParent()230     private boolean endsXEnclosedWithinParent() {
231         return mWidth <= mParentWidth
232                 && mToXDelta + mWidth <= mParentWidth
233                 && mToXDelta >= 0;
234     }
235 
startsXEnclosedWithinParent()236     private boolean startsXEnclosedWithinParent() {
237         return mWidth <= mParentWidth
238                 && mFromXDelta + mWidth <= mParentWidth
239                 && mFromXDelta >= 0;
240     }
241 }
242