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.content.Context; 20 import android.content.res.Resources; 21 import android.content.res.TypedArray; 22 import android.util.AttributeSet; 23 import android.util.TypedValue; 24 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 */ 30 public class ScaleAnimation extends Animation { 31 private final Resources mResources; 32 33 private float mFromX; 34 private float mToX; 35 private float mFromY; 36 private float mToY; 37 38 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 48 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 /** 57 * Constructor used when a ScaleAnimation is loaded from a resource. 58 * 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 65 mResources = context.getResources(); 66 67 TypedArray a = context.obtainStyledAttributes(attrs, 68 com.android.internal.R.styleable.ScaleAnimation); 69 70 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 } 94 95 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 } 119 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(); 131 132 initializePivotPoint(); 133 } 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) { 146 mResources = null; 147 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) { 173 mResources = null; 174 mFromX = fromX; 175 mToX = toX; 176 mFromY = fromY; 177 mToY = toY; 178 179 mPivotXType = ABSOLUTE; 180 mPivotYType = ABSOLUTE; 181 mPivotXValue = pivotX; 182 mPivotYValue = pivotY; 183 initializePivotPoint(); 184 } 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) { 214 mResources = null; 215 mFromX = fromX; 216 mToX = toX; 217 mFromY = fromY; 218 mToY = toY; 219 220 mPivotXValue = pivotXValue; 221 mPivotXType = pivotXType; 222 mPivotYValue = pivotYValue; 223 mPivotYType = pivotYType; 224 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 } 238 } 239 240 @Override 241 protected void applyTransformation(float interpolatedTime, Transformation t) { 242 float sx = 1.0f; 243 float sy = 1.0f; 244 float scale = getScaleFactor(); 245 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 { 256 t.getMatrix().setScale(sx, sy, scale * mPivotX, scale * mPivotY); 257 } 258 } 259 260 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 277 @Override 278 public void initialize(int width, int height, int parentWidth, int parentHeight) { 279 super.initialize(width, height, parentWidth, parentHeight); 280 281 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 286 mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth); 287 mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight); 288 } 289 } 290