mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 11:18:21 +00:00
169 lines
5.1 KiB
Java
169 lines
5.1 KiB
Java
|
|
package com.android.launcher3;
|
||
|
|
|
||
|
|
import android.animation.ObjectAnimator;
|
||
|
|
import android.content.res.Resources;
|
||
|
|
import android.graphics.Bitmap;
|
||
|
|
import android.graphics.BitmapFactory;
|
||
|
|
import android.graphics.Canvas;
|
||
|
|
import android.graphics.ColorFilter;
|
||
|
|
import android.graphics.Paint;
|
||
|
|
import android.graphics.Path;
|
||
|
|
import android.graphics.PixelFormat;
|
||
|
|
import android.graphics.Rect;
|
||
|
|
import android.graphics.RectF;
|
||
|
|
import android.graphics.drawable.Drawable;
|
||
|
|
|
||
|
|
class PreloadIconDrawable extends Drawable {
|
||
|
|
private static final float ANIMATION_PROGRESS_STOPPED = -1.0f;
|
||
|
|
private static final float ANIMATION_PROGRESS_STARTED = 0f;
|
||
|
|
private static final float ANIMATION_PROGRESS_COMPLETED = 1.0f;
|
||
|
|
|
||
|
|
private static final float ICON_SCALE_FACTOR = 0.6f;
|
||
|
|
|
||
|
|
private static Bitmap sProgressBg, sProgressFill;
|
||
|
|
|
||
|
|
private final Rect mCanvasClipRect = new Rect();
|
||
|
|
private final RectF mRect = new RectF();
|
||
|
|
private final Path mProgressPath = new Path();
|
||
|
|
private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
|
||
|
|
|
||
|
|
final Drawable mIcon;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Indicates the progress of the preloader [0-100]. If it goes above 100, only the icon
|
||
|
|
* is shown with no progress bar.
|
||
|
|
*/
|
||
|
|
private int mProgress = 0;
|
||
|
|
private boolean mPathChanged;
|
||
|
|
|
||
|
|
private float mAnimationProgress = ANIMATION_PROGRESS_STOPPED;
|
||
|
|
private ObjectAnimator mAnimator;
|
||
|
|
|
||
|
|
public PreloadIconDrawable(Drawable icon, Resources res) {
|
||
|
|
mIcon = icon;
|
||
|
|
|
||
|
|
setBounds(icon.getBounds());
|
||
|
|
mPathChanged = false;
|
||
|
|
|
||
|
|
if (sProgressBg == null) {
|
||
|
|
sProgressBg = BitmapFactory.decodeResource(res, R.drawable.bg_preloader);
|
||
|
|
}
|
||
|
|
if (sProgressFill == null) {
|
||
|
|
sProgressFill = BitmapFactory.decodeResource(res, R.drawable.bg_preloader_progress);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public void draw(Canvas canvas) {
|
||
|
|
final Rect r = getBounds();
|
||
|
|
if (canvas.getClipBounds(mCanvasClipRect) && !Rect.intersects(mCanvasClipRect, r)) {
|
||
|
|
// The draw region has been clipped.
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
final float iconScale;
|
||
|
|
|
||
|
|
if ((mAnimationProgress >= ANIMATION_PROGRESS_STARTED)
|
||
|
|
&& (mAnimationProgress < ANIMATION_PROGRESS_COMPLETED)) {
|
||
|
|
mPaint.setAlpha((int) ((1 - mAnimationProgress) * 255));
|
||
|
|
canvas.drawBitmap(sProgressBg, null, r, mPaint);
|
||
|
|
canvas.drawBitmap(sProgressFill, null, r, mPaint);
|
||
|
|
iconScale = ICON_SCALE_FACTOR + (1 - ICON_SCALE_FACTOR) * mAnimationProgress;
|
||
|
|
|
||
|
|
} else if (mAnimationProgress == ANIMATION_PROGRESS_STOPPED) {
|
||
|
|
mPaint.setAlpha(255);
|
||
|
|
iconScale = ICON_SCALE_FACTOR;
|
||
|
|
canvas.drawBitmap(sProgressBg, null, r, mPaint);
|
||
|
|
|
||
|
|
if (mProgress >= 100) {
|
||
|
|
canvas.drawBitmap(sProgressFill, null, r, mPaint);
|
||
|
|
} else if (mProgress > 0) {
|
||
|
|
if (mPathChanged) {
|
||
|
|
mProgressPath.reset();
|
||
|
|
mProgressPath.moveTo(r.exactCenterX(), r.centerY());
|
||
|
|
|
||
|
|
mRect.set(r);
|
||
|
|
mProgressPath.arcTo(mRect, -90, mProgress * 3.6f);
|
||
|
|
mProgressPath.close();
|
||
|
|
mPathChanged = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
canvas.save();
|
||
|
|
canvas.clipPath(mProgressPath);
|
||
|
|
canvas.drawBitmap(sProgressFill, null, r, mPaint);
|
||
|
|
canvas.restore();
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
iconScale = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
canvas.save();
|
||
|
|
canvas.scale(iconScale, iconScale, r.exactCenterX(), r.exactCenterY());
|
||
|
|
mIcon.draw(canvas);
|
||
|
|
canvas.restore();
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
protected void onBoundsChange(Rect bounds) {
|
||
|
|
mIcon.setBounds(bounds);
|
||
|
|
mPathChanged = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public int getOpacity() {
|
||
|
|
return PixelFormat.TRANSLUCENT;
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public void setAlpha(int alpha) {
|
||
|
|
mIcon.setAlpha(alpha);
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public void setColorFilter(ColorFilter cf) {
|
||
|
|
mIcon.setColorFilter(cf);
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
protected boolean onLevelChange(int level) {
|
||
|
|
mProgress = level;
|
||
|
|
mPathChanged = true;
|
||
|
|
|
||
|
|
// Stop Animation
|
||
|
|
if (mAnimator != null) {
|
||
|
|
mAnimator.cancel();
|
||
|
|
mAnimator = null;
|
||
|
|
}
|
||
|
|
mAnimationProgress = ANIMATION_PROGRESS_STOPPED;
|
||
|
|
|
||
|
|
invalidateSelf();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Runs the finish animation if it is has not been run after last level change.
|
||
|
|
*/
|
||
|
|
public void maybePerformFinishedAnimation() {
|
||
|
|
if (mAnimationProgress > ANIMATION_PROGRESS_STOPPED) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (mAnimator != null) {
|
||
|
|
mAnimator.cancel();
|
||
|
|
}
|
||
|
|
setAnimationProgress(ANIMATION_PROGRESS_STARTED);
|
||
|
|
mAnimator = ObjectAnimator.ofFloat(this, "animationProgress",
|
||
|
|
ANIMATION_PROGRESS_STARTED, ANIMATION_PROGRESS_COMPLETED);
|
||
|
|
mAnimator.start();
|
||
|
|
}
|
||
|
|
|
||
|
|
public void setAnimationProgress(float progress) {
|
||
|
|
if (progress != mAnimationProgress) {
|
||
|
|
mAnimationProgress = progress;
|
||
|
|
invalidateSelf();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public float getAnimationProgress() {
|
||
|
|
return mAnimationProgress;
|
||
|
|
}
|
||
|
|
}
|