| /* |
| * Copyright (C) 2006 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.view.animation; |
| |
| import android.content.Context; |
| import android.content.res.Resources; |
| import android.content.res.TypedArray; |
| import android.util.AttributeSet; |
| import android.util.TypedValue; |
| |
| /** |
| * An animation that controls the scale of an object. You can specify the point |
| * to use for the center of scaling. |
| * |
| */ |
| public class ScaleAnimation extends Animation { |
| private final Resources mResources; |
| |
| private float mFromX; |
| private float mToX; |
| private float mFromY; |
| private float mToY; |
| |
| private int mFromXType = TypedValue.TYPE_NULL; |
| private int mToXType = TypedValue.TYPE_NULL; |
| private int mFromYType = TypedValue.TYPE_NULL; |
| private int mToYType = TypedValue.TYPE_NULL; |
| |
| private int mFromXData = 0; |
| private int mToXData = 0; |
| private int mFromYData = 0; |
| private int mToYData = 0; |
| |
| private int mPivotXType = ABSOLUTE; |
| private int mPivotYType = ABSOLUTE; |
| private float mPivotXValue = 0.0f; |
| private float mPivotYValue = 0.0f; |
| |
| private float mPivotX; |
| private float mPivotY; |
| |
| /** |
| * Constructor used when a ScaleAnimation is loaded from a resource. |
| * |
| * @param context Application context to use |
| * @param attrs Attribute set from which to read values |
| */ |
| public ScaleAnimation(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| |
| mResources = context.getResources(); |
| |
| TypedArray a = context.obtainStyledAttributes(attrs, |
| com.android.internal.R.styleable.ScaleAnimation); |
| |
| TypedValue tv = a.peekValue( |
| com.android.internal.R.styleable.ScaleAnimation_fromXScale); |
| mFromX = 0.0f; |
| if (tv != null) { |
| if (tv.type == TypedValue.TYPE_FLOAT) { |
| // This is a scaling factor. |
| mFromX = tv.getFloat(); |
| } else { |
| mFromXType = tv.type; |
| mFromXData = tv.data; |
| } |
| } |
| tv = a.peekValue( |
| com.android.internal.R.styleable.ScaleAnimation_toXScale); |
| mToX = 0.0f; |
| if (tv != null) { |
| if (tv.type == TypedValue.TYPE_FLOAT) { |
| // This is a scaling factor. |
| mToX = tv.getFloat(); |
| } else { |
| mToXType = tv.type; |
| mToXData = tv.data; |
| } |
| } |
| |
| tv = a.peekValue( |
| com.android.internal.R.styleable.ScaleAnimation_fromYScale); |
| mFromY = 0.0f; |
| if (tv != null) { |
| if (tv.type == TypedValue.TYPE_FLOAT) { |
| // This is a scaling factor. |
| mFromY = tv.getFloat(); |
| } else { |
| mFromYType = tv.type; |
| mFromYData = tv.data; |
| } |
| } |
| tv = a.peekValue( |
| com.android.internal.R.styleable.ScaleAnimation_toYScale); |
| mToY = 0.0f; |
| if (tv != null) { |
| if (tv.type == TypedValue.TYPE_FLOAT) { |
| // This is a scaling factor. |
| mToY = tv.getFloat(); |
| } else { |
| mToYType = tv.type; |
| mToYData = tv.data; |
| } |
| } |
| |
| Description d = Description.parseValue(a.peekValue( |
| com.android.internal.R.styleable.ScaleAnimation_pivotX)); |
| mPivotXType = d.type; |
| mPivotXValue = d.value; |
| |
| d = Description.parseValue(a.peekValue( |
| com.android.internal.R.styleable.ScaleAnimation_pivotY)); |
| mPivotYType = d.type; |
| mPivotYValue = d.value; |
| |
| a.recycle(); |
| |
| initializePivotPoint(); |
| } |
| |
| /** |
| * Constructor to use when building a ScaleAnimation from code |
| * |
| * @param fromX Horizontal scaling factor to apply at the start of the |
| * animation |
| * @param toX Horizontal scaling factor to apply at the end of the animation |
| * @param fromY Vertical scaling factor to apply at the start of the |
| * animation |
| * @param toY Vertical scaling factor to apply at the end of the animation |
| */ |
| public ScaleAnimation(float fromX, float toX, float fromY, float toY) { |
| mResources = null; |
| mFromX = fromX; |
| mToX = toX; |
| mFromY = fromY; |
| mToY = toY; |
| mPivotX = 0; |
| mPivotY = 0; |
| } |
| |
| /** |
| * Constructor to use when building a ScaleAnimation from code |
| * |
| * @param fromX Horizontal scaling factor to apply at the start of the |
| * animation |
| * @param toX Horizontal scaling factor to apply at the end of the animation |
| * @param fromY Vertical scaling factor to apply at the start of the |
| * animation |
| * @param toY Vertical scaling factor to apply at the end of the animation |
| * @param pivotX The X coordinate of the point about which the object is |
| * being scaled, specified as an absolute number where 0 is the left |
| * edge. (This point remains fixed while the object changes size.) |
| * @param pivotY The Y coordinate of the point about which the object is |
| * being scaled, specified as an absolute number where 0 is the top |
| * edge. (This point remains fixed while the object changes size.) |
| */ |
| public ScaleAnimation(float fromX, float toX, float fromY, float toY, |
| float pivotX, float pivotY) { |
| mResources = null; |
| mFromX = fromX; |
| mToX = toX; |
| mFromY = fromY; |
| mToY = toY; |
| |
| mPivotXType = ABSOLUTE; |
| mPivotYType = ABSOLUTE; |
| mPivotXValue = pivotX; |
| mPivotYValue = pivotY; |
| initializePivotPoint(); |
| } |
| |
| /** |
| * Constructor to use when building a ScaleAnimation from code |
| * |
| * @param fromX Horizontal scaling factor to apply at the start of the |
| * animation |
| * @param toX Horizontal scaling factor to apply at the end of the animation |
| * @param fromY Vertical scaling factor to apply at the start of the |
| * animation |
| * @param toY Vertical scaling factor to apply at the end of the animation |
| * @param pivotXType Specifies how pivotXValue should be interpreted. One of |
| * Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or |
| * Animation.RELATIVE_TO_PARENT. |
| * @param pivotXValue The X coordinate of the point about which the object |
| * is being scaled, specified as an absolute number where 0 is the |
| * left edge. (This point remains fixed while the object changes |
| * size.) This value can either be an absolute number if pivotXType |
| * is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise. |
| * @param pivotYType Specifies how pivotYValue should be interpreted. One of |
| * Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or |
| * Animation.RELATIVE_TO_PARENT. |
| * @param pivotYValue The Y coordinate of the point about which the object |
| * is being scaled, specified as an absolute number where 0 is the |
| * top edge. (This point remains fixed while the object changes |
| * size.) This value can either be an absolute number if pivotYType |
| * is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise. |
| */ |
| public ScaleAnimation(float fromX, float toX, float fromY, float toY, |
| int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) { |
| mResources = null; |
| mFromX = fromX; |
| mToX = toX; |
| mFromY = fromY; |
| mToY = toY; |
| |
| mPivotXValue = pivotXValue; |
| mPivotXType = pivotXType; |
| mPivotYValue = pivotYValue; |
| mPivotYType = pivotYType; |
| initializePivotPoint(); |
| } |
| |
| /** |
| * Called at the end of constructor methods to initialize, if possible, values for |
| * the pivot point. This is only possible for ABSOLUTE pivot values. |
| */ |
| private void initializePivotPoint() { |
| if (mPivotXType == ABSOLUTE) { |
| mPivotX = mPivotXValue; |
| } |
| if (mPivotYType == ABSOLUTE) { |
| mPivotY = mPivotYValue; |
| } |
| } |
| |
| @Override |
| protected void applyTransformation(float interpolatedTime, Transformation t) { |
| float sx = 1.0f; |
| float sy = 1.0f; |
| float scale = getScaleFactor(); |
| |
| if (mFromX != 1.0f || mToX != 1.0f) { |
| sx = mFromX + ((mToX - mFromX) * interpolatedTime); |
| } |
| if (mFromY != 1.0f || mToY != 1.0f) { |
| sy = mFromY + ((mToY - mFromY) * interpolatedTime); |
| } |
| |
| if (mPivotX == 0 && mPivotY == 0) { |
| t.getMatrix().setScale(sx, sy); |
| } else { |
| t.getMatrix().setScale(sx, sy, scale * mPivotX, scale * mPivotY); |
| } |
| } |
| |
| float resolveScale(float scale, int type, int data, int size, int psize) { |
| float targetSize; |
| if (type == TypedValue.TYPE_FRACTION) { |
| targetSize = TypedValue.complexToFraction(data, size, psize); |
| } else if (type == TypedValue.TYPE_DIMENSION) { |
| targetSize = TypedValue.complexToDimension(data, mResources.getDisplayMetrics()); |
| } else { |
| return scale; |
| } |
| |
| if (size == 0) { |
| return 1; |
| } |
| |
| return targetSize/(float)size; |
| } |
| |
| @Override |
| public void initialize(int width, int height, int parentWidth, int parentHeight) { |
| super.initialize(width, height, parentWidth, parentHeight); |
| |
| mFromX = resolveScale(mFromX, mFromXType, mFromXData, width, parentWidth); |
| mToX = resolveScale(mToX, mToXType, mToXData, width, parentWidth); |
| mFromY = resolveScale(mFromY, mFromYType, mFromYData, height, parentHeight); |
| mToY = resolveScale(mToY, mToYType, mToYData, height, parentHeight); |
| |
| mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth); |
| mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight); |
| } |
| } |