TileDrawable.java revision df3da61c8f2f54604376d9761649bdba54aa858b
151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (C) 2013 The Android Open Source Project 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Licensed under the Apache License, Version 2.0 (the "License"); 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * you may not use this file except in compliance with the License. 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You may obtain a copy of the License at 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * http://www.apache.org/licenses/LICENSE-2.0 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Unless required by applicable law or agreed to in writing, software 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * distributed under the License is distributed on an "AS IS" BASIS, 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * See the License for the specific language governing permissions and 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * limitations under the License. 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage com.android.bitmap.drawable; 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport android.animation.ValueAnimator; 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport android.animation.ValueAnimator.AnimatorUpdateListener; 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport android.graphics.Canvas; 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport android.graphics.ColorFilter; 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport android.graphics.Paint; 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport android.graphics.Rect; 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport android.graphics.drawable.Drawable; 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport com.android.bitmap.drawable.ExtendedBitmapDrawable.ExtendedOptions; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A drawable that wraps another drawable and places it in the center of this space. This drawable 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * allows a background color for the "tile", and has a fade-out transition when 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link #setVisible(boolean, boolean)} indicates that it is no longer visible. 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class TileDrawable extends Drawable implements Drawable.Callback { 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final ExtendedOptions mOpts; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Paint mPaint = new Paint(); 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Drawable mInner; 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final int mInnerWidth; 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final int mInnerHeight; 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected final ValueAnimator mFadeOutAnimator; 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public TileDrawable(Drawable inner, int innerWidth, int innerHeight, int fadeOutDurationMs, 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ExtendedOptions opts) { 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mOpts = opts; 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mInner = inner != null ? inner.mutate() : null; 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mInnerWidth = innerWidth; 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mInnerHeight = innerHeight; 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (inner != null) { 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mInner.setCallback(this); 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mFadeOutAnimator = ValueAnimator.ofInt(255, 0) 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski .setDuration(fadeOutDurationMs); 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mFadeOutAnimator.addUpdateListener(new AnimatorUpdateListener() { 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void onAnimationUpdate(ValueAnimator animation) { 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setAlpha((Integer) animation.getAnimatedValue()); 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }); 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski reset(); 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void reset() { 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setAlpha(0); 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setVisible(false); 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void onBoundsChange(Rect bounds) { 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super.onBoundsChange(bounds); 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (mInner == null) { 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bounds.isEmpty()) { 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mInner.setBounds(0, 0, 0, 0); 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final int l = bounds.left + (bounds.width() / 2) - (mInnerWidth / 2); 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final int t = bounds.top + (bounds.height() / 2) - (mInnerHeight / 2); 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mInner.setBounds(l, t, l + mInnerWidth, t + mInnerHeight); 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void draw(Canvas canvas) { 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isVisible() && mPaint.getAlpha() == 0) { 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final int alpha = mPaint.getAlpha(); 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mPaint.setColor(mOpts.backgroundColor); 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mPaint.setAlpha(alpha); 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski canvas.drawRect(getBounds(), mPaint); 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (mInner != null) mInner.draw(canvas); 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void setAlpha(int alpha) { 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final int old = mPaint.getAlpha(); 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mPaint.setAlpha(alpha); 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setInnerAlpha(alpha); 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (alpha != old) { 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski invalidateSelf(); 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void setColorFilter(ColorFilter cf) { 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mPaint.setColorFilter(cf); 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (mInner != null) mInner.setColorFilter(cf); 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getOpacity() { 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected int getCurrentAlpha() { 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return mPaint.getAlpha(); 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean setVisible(boolean visible) { 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return setVisible(visible, true /* dontcare */); 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean setVisible(boolean visible, boolean restart) { 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (mInner != null) mInner.setVisible(visible, restart); 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final boolean changed = super.setVisible(visible, restart); 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (changed) { 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isVisible()) { 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // pop in (no-op) 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the transition will still be smooth if the previous state's layer fades out 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mFadeOutAnimator.cancel(); 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setAlpha(255); 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // fade out 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (mPaint.getAlpha() == 255 && !getBounds().isEmpty()) { 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mFadeOutAnimator.start(); 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return changed; 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected boolean onLevelChange(int level) { 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (mInner != null) 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return mInner.setLevel(level); 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else { 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return super.onLevelChange(level); 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Changes the alpha on just the inner wrapped drawable. 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void setInnerAlpha(int alpha) { 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (mInner != null) mInner.setAlpha(alpha); 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void invalidateDrawable(Drawable who) { 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski invalidateSelf(); 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void scheduleDrawable(Drawable who, Runnable what, long when) { 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski scheduleSelf(what, when); 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void unscheduleDrawable(Drawable who, Runnable what) { 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unscheduleSelf(what); 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski