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