Home | History | Annotate | Download | only in bitmap
      1 package com.android.mail.bitmap;
      2 
      3 import android.animation.ValueAnimator;
      4 import android.animation.ValueAnimator.AnimatorUpdateListener;
      5 import android.graphics.Canvas;
      6 import android.graphics.ColorFilter;
      7 import android.graphics.Paint;
      8 import android.graphics.Rect;
      9 import android.graphics.drawable.Drawable;
     10 
     11 /**
     12  * A drawable that wraps another drawable and places it in the center of this space. This drawable
     13  * allows a background color for the "tile", and has a fade-out transition when
     14  * {@link #setVisible(boolean, boolean)} indicates that it is no longer visible.
     15  */
     16 public class TileDrawable extends Drawable implements Drawable.Callback {
     17 
     18     private final Paint mPaint = new Paint();
     19     private final Drawable mInner;
     20     private final int mInnerWidth;
     21     private final int mInnerHeight;
     22 
     23     protected final ValueAnimator mFadeOutAnimator;
     24 
     25     public TileDrawable(Drawable inner, int innerWidth, int innerHeight,
     26             int backgroundColor, int fadeOutDurationMs) {
     27         mInner = inner.mutate();
     28         mInnerWidth = innerWidth;
     29         mInnerHeight = innerHeight;
     30         mPaint.setColor(backgroundColor);
     31         mInner.setCallback(this);
     32 
     33         mFadeOutAnimator = ValueAnimator.ofInt(255, 0)
     34                 .setDuration(fadeOutDurationMs);
     35         mFadeOutAnimator.addUpdateListener(new AnimatorUpdateListener() {
     36             @Override
     37             public void onAnimationUpdate(ValueAnimator animation) {
     38                 setAlpha((Integer) animation.getAnimatedValue());
     39             }
     40         });
     41 
     42         reset();
     43     }
     44 
     45     public void reset() {
     46         setAlpha(0);
     47         setVisible(false);
     48     }
     49 
     50     @Override
     51     protected void onBoundsChange(Rect bounds) {
     52         super.onBoundsChange(bounds);
     53 
     54         if (bounds.isEmpty()) {
     55             mInner.setBounds(0, 0, 0, 0);
     56         } else {
     57             final int l = bounds.left + (bounds.width() / 2) - (mInnerWidth / 2);
     58             final int t = bounds.top + (bounds.height() / 2) - (mInnerHeight / 2);
     59             mInner.setBounds(l, t, l + mInnerWidth, t + mInnerHeight);
     60         }
     61     }
     62 
     63     @Override
     64     public void draw(Canvas canvas) {
     65         if (!isVisible() && mPaint.getAlpha() == 0) {
     66             return;
     67         }
     68         canvas.drawRect(getBounds(), mPaint);
     69         mInner.draw(canvas);
     70     }
     71 
     72     @Override
     73     public void setAlpha(int alpha) {
     74         final int old = mPaint.getAlpha();
     75         mPaint.setAlpha(alpha);
     76         setInnerAlpha(alpha);
     77         if (alpha != old) {
     78             invalidateSelf();
     79         }
     80     }
     81 
     82     @Override
     83     public void setColorFilter(ColorFilter cf) {
     84         mPaint.setColorFilter(cf);
     85         mInner.setColorFilter(cf);
     86     }
     87 
     88     @Override
     89     public int getOpacity() {
     90         return 0;
     91     }
     92 
     93     protected int getCurrentAlpha() {
     94         return mPaint.getAlpha();
     95     }
     96 
     97     public boolean setVisible(boolean visible) {
     98         return setVisible(visible, true /* dontcare */);
     99     }
    100 
    101     @Override
    102     public boolean setVisible(boolean visible, boolean restart) {
    103         mInner.setVisible(visible, restart);
    104         final boolean changed = super.setVisible(visible, restart);
    105         if (changed) {
    106             if (isVisible()) {
    107                 // pop in (no-op)
    108                 // the transition will still be smooth if the previous state's layer fades out
    109                 mFadeOutAnimator.cancel();
    110                 setAlpha(255);
    111             } else {
    112                 // fade out
    113                 if (mPaint.getAlpha() == 255 && !getBounds().isEmpty()) {
    114                     mFadeOutAnimator.start();
    115                 }
    116             }
    117         }
    118         return changed;
    119     }
    120 
    121     @Override
    122     protected boolean onLevelChange(int level) {
    123         return mInner.setLevel(level);
    124     }
    125 
    126     /**
    127      * Changes the alpha on just the inner wrapped drawable.
    128      */
    129     public void setInnerAlpha(int alpha) {
    130         mInner.setAlpha(alpha);
    131     }
    132 
    133     @Override
    134     public void invalidateDrawable(Drawable who) {
    135         invalidateSelf();
    136     }
    137 
    138     @Override
    139     public void scheduleDrawable(Drawable who, Runnable what, long when) {
    140         scheduleSelf(what, when);
    141     }
    142 
    143     @Override
    144     public void unscheduleDrawable(Drawable who, Runnable what) {
    145         unscheduleSelf(what);
    146     }
    147 
    148 }
    149