Home | History | Annotate | Download | only in animation
      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