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 */ ScaleAnimation(Context context, AttributeSet attrs)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 */ ScaleAnimation(float fromX, float toX, float fromY, float toY)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 */ ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)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 */ ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)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 */ initializePivotPoint()231 private void initializePivotPoint() { 232 if (mPivotXType == ABSOLUTE) { 233 mPivotX = mPivotXValue; 234 } 235 if (mPivotYType == ABSOLUTE) { 236 mPivotY = mPivotYValue; 237 } 238 } 239 240 @Override applyTransformation(float interpolatedTime, Transformation t)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 resolveScale(float scale, int type, int data, int size, int psize)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 initialize(int width, int height, int parentWidth, int parentHeight)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