blob: e9a84364452cd1bd1a6e456bfa221e86c4b5b4cf [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.view.animation;
18
19import android.content.Context;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080020import android.content.res.Resources;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.res.TypedArray;
22import android.util.AttributeSet;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080023import android.util.TypedValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
25/**
26 * An animation that controls the scale of an object. You can specify the point
27 * to use for the center of scaling.
28 *
29 */
30public class ScaleAnimation extends Animation {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080031 private final Resources mResources;
32
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033 private float mFromX;
34 private float mToX;
35 private float mFromY;
36 private float mToY;
37
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080038 private int mFromXType = TypedValue.TYPE_NULL;
39 private int mToXType = TypedValue.TYPE_NULL;
40 private int mFromYType = TypedValue.TYPE_NULL;
41 private int mToYType = TypedValue.TYPE_NULL;
42
43 private int mFromXData = 0;
44 private int mToXData = 0;
45 private int mFromYData = 0;
46 private int mToYData = 0;
47
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048 private int mPivotXType = ABSOLUTE;
49 private int mPivotYType = ABSOLUTE;
50 private float mPivotXValue = 0.0f;
51 private float mPivotYValue = 0.0f;
52
53 private float mPivotX;
54 private float mPivotY;
55
56 /**
The Android Open Source Projectbdbdc4f2009-03-03 21:00:54 -080057 * Constructor used when a ScaleAnimation is loaded from a resource.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 *
59 * @param context Application context to use
60 * @param attrs Attribute set from which to read values
61 */
62 public ScaleAnimation(Context context, AttributeSet attrs) {
63 super(context, attrs);
64
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080065 mResources = context.getResources();
66
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 TypedArray a = context.obtainStyledAttributes(attrs,
68 com.android.internal.R.styleable.ScaleAnimation);
69
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080070 TypedValue tv = a.peekValue(
71 com.android.internal.R.styleable.ScaleAnimation_fromXScale);
72 mFromX = 0.0f;
73 if (tv != null) {
74 if (tv.type == TypedValue.TYPE_FLOAT) {
75 // This is a scaling factor.
76 mFromX = tv.getFloat();
77 } else {
78 mFromXType = tv.type;
79 mFromXData = tv.data;
80 }
81 }
82 tv = a.peekValue(
83 com.android.internal.R.styleable.ScaleAnimation_toXScale);
84 mToX = 0.0f;
85 if (tv != null) {
86 if (tv.type == TypedValue.TYPE_FLOAT) {
87 // This is a scaling factor.
88 mToX = tv.getFloat();
89 } else {
90 mToXType = tv.type;
91 mToXData = tv.data;
92 }
93 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080095 tv = a.peekValue(
96 com.android.internal.R.styleable.ScaleAnimation_fromYScale);
97 mFromY = 0.0f;
98 if (tv != null) {
99 if (tv.type == TypedValue.TYPE_FLOAT) {
100 // This is a scaling factor.
101 mFromY = tv.getFloat();
102 } else {
103 mFromYType = tv.type;
104 mFromYData = tv.data;
105 }
106 }
107 tv = a.peekValue(
108 com.android.internal.R.styleable.ScaleAnimation_toYScale);
109 mToY = 0.0f;
110 if (tv != null) {
111 if (tv.type == TypedValue.TYPE_FLOAT) {
112 // This is a scaling factor.
113 mToY = tv.getFloat();
114 } else {
115 mToYType = tv.type;
116 mToYData = tv.data;
117 }
118 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119
120 Description d = Description.parseValue(a.peekValue(
121 com.android.internal.R.styleable.ScaleAnimation_pivotX));
122 mPivotXType = d.type;
123 mPivotXValue = d.value;
124
125 d = Description.parseValue(a.peekValue(
126 com.android.internal.R.styleable.ScaleAnimation_pivotY));
127 mPivotYType = d.type;
128 mPivotYValue = d.value;
129
130 a.recycle();
Chet Haase84c949f2011-12-20 10:38:31 -0800131
132 initializePivotPoint();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 }
134
135 /**
136 * Constructor to use when building a ScaleAnimation from code
137 *
138 * @param fromX Horizontal scaling factor to apply at the start of the
139 * animation
140 * @param toX Horizontal scaling factor to apply at the end of the animation
141 * @param fromY Vertical scaling factor to apply at the start of the
142 * animation
143 * @param toY Vertical scaling factor to apply at the end of the animation
144 */
145 public ScaleAnimation(float fromX, float toX, float fromY, float toY) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800146 mResources = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 mFromX = fromX;
148 mToX = toX;
149 mFromY = fromY;
150 mToY = toY;
151 mPivotX = 0;
152 mPivotY = 0;
153 }
154
155 /**
156 * Constructor to use when building a ScaleAnimation from code
157 *
158 * @param fromX Horizontal scaling factor to apply at the start of the
159 * animation
160 * @param toX Horizontal scaling factor to apply at the end of the animation
161 * @param fromY Vertical scaling factor to apply at the start of the
162 * animation
163 * @param toY Vertical scaling factor to apply at the end of the animation
164 * @param pivotX The X coordinate of the point about which the object is
165 * being scaled, specified as an absolute number where 0 is the left
166 * edge. (This point remains fixed while the object changes size.)
167 * @param pivotY The Y coordinate of the point about which the object is
168 * being scaled, specified as an absolute number where 0 is the top
169 * edge. (This point remains fixed while the object changes size.)
170 */
171 public ScaleAnimation(float fromX, float toX, float fromY, float toY,
172 float pivotX, float pivotY) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800173 mResources = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 mFromX = fromX;
175 mToX = toX;
176 mFromY = fromY;
177 mToY = toY;
178
179 mPivotXType = ABSOLUTE;
180 mPivotYType = ABSOLUTE;
181 mPivotXValue = pivotX;
182 mPivotYValue = pivotY;
Chet Haase84c949f2011-12-20 10:38:31 -0800183 initializePivotPoint();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 }
185
186 /**
187 * Constructor to use when building a ScaleAnimation from code
188 *
189 * @param fromX Horizontal scaling factor to apply at the start of the
190 * animation
191 * @param toX Horizontal scaling factor to apply at the end of the animation
192 * @param fromY Vertical scaling factor to apply at the start of the
193 * animation
194 * @param toY Vertical scaling factor to apply at the end of the animation
195 * @param pivotXType Specifies how pivotXValue should be interpreted. One of
196 * Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
197 * Animation.RELATIVE_TO_PARENT.
198 * @param pivotXValue The X coordinate of the point about which the object
199 * is being scaled, specified as an absolute number where 0 is the
200 * left edge. (This point remains fixed while the object changes
201 * size.) This value can either be an absolute number if pivotXType
202 * is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
203 * @param pivotYType Specifies how pivotYValue should be interpreted. One of
204 * Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
205 * Animation.RELATIVE_TO_PARENT.
206 * @param pivotYValue The Y coordinate of the point about which the object
207 * is being scaled, specified as an absolute number where 0 is the
208 * top edge. (This point remains fixed while the object changes
209 * size.) This value can either be an absolute number if pivotYType
210 * is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
211 */
212 public ScaleAnimation(float fromX, float toX, float fromY, float toY,
213 int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800214 mResources = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 mFromX = fromX;
216 mToX = toX;
217 mFromY = fromY;
218 mToY = toY;
219
220 mPivotXValue = pivotXValue;
221 mPivotXType = pivotXType;
222 mPivotYValue = pivotYValue;
223 mPivotYType = pivotYType;
Chet Haase84c949f2011-12-20 10:38:31 -0800224 initializePivotPoint();
225 }
226
227 /**
228 * Called at the end of constructor methods to initialize, if possible, values for
229 * the pivot point. This is only possible for ABSOLUTE pivot values.
230 */
231 private void initializePivotPoint() {
232 if (mPivotXType == ABSOLUTE) {
233 mPivotX = mPivotXValue;
234 }
235 if (mPivotYType == ABSOLUTE) {
236 mPivotY = mPivotYValue;
237 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238 }
239
240 @Override
241 protected void applyTransformation(float interpolatedTime, Transformation t) {
242 float sx = 1.0f;
243 float sy = 1.0f;
Chet Haase48460322010-06-11 14:22:25 -0700244 float scale = getScaleFactor();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245
246 if (mFromX != 1.0f || mToX != 1.0f) {
247 sx = mFromX + ((mToX - mFromX) * interpolatedTime);
248 }
249 if (mFromY != 1.0f || mToY != 1.0f) {
250 sy = mFromY + ((mToY - mFromY) * interpolatedTime);
251 }
252
253 if (mPivotX == 0 && mPivotY == 0) {
254 t.getMatrix().setScale(sx, sy);
255 } else {
Chet Haase48460322010-06-11 14:22:25 -0700256 t.getMatrix().setScale(sx, sy, scale * mPivotX, scale * mPivotY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 }
258 }
259
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800260 float resolveScale(float scale, int type, int data, int size, int psize) {
261 float targetSize;
262 if (type == TypedValue.TYPE_FRACTION) {
263 targetSize = TypedValue.complexToFraction(data, size, psize);
264 } else if (type == TypedValue.TYPE_DIMENSION) {
265 targetSize = TypedValue.complexToDimension(data, mResources.getDisplayMetrics());
266 } else {
267 return scale;
268 }
269
270 if (size == 0) {
271 return 1;
272 }
273
274 return targetSize/(float)size;
275 }
276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 @Override
278 public void initialize(int width, int height, int parentWidth, int parentHeight) {
279 super.initialize(width, height, parentWidth, parentHeight);
280
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800281 mFromX = resolveScale(mFromX, mFromXType, mFromXData, width, parentWidth);
282 mToX = resolveScale(mToX, mToXType, mToXData, width, parentWidth);
283 mFromY = resolveScale(mFromY, mFromYType, mFromYData, height, parentHeight);
284 mToY = resolveScale(mToY, mToYType, mToYData, height, parentHeight);
285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
287 mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
288 }
289}