Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'android/3rd_party/HoloEverywhere/library/src/org/holoeverywhere/widget/ProgressBar.java')
-rw-r--r--android/3rd_party/HoloEverywhere/library/src/org/holoeverywhere/widget/ProgressBar.java870
1 files changed, 870 insertions, 0 deletions
diff --git a/android/3rd_party/HoloEverywhere/library/src/org/holoeverywhere/widget/ProgressBar.java b/android/3rd_party/HoloEverywhere/library/src/org/holoeverywhere/widget/ProgressBar.java
new file mode 100644
index 0000000000..2b91824765
--- /dev/null
+++ b/android/3rd_party/HoloEverywhere/library/src/org/holoeverywhere/widget/ProgressBar.java
@@ -0,0 +1,870 @@
+
+package org.holoeverywhere.widget;
+
+import java.util.ArrayList;
+
+import org.holoeverywhere.R;
+import org.holoeverywhere.drawable.DrawableCompat;
+import org.holoeverywhere.internal._View;
+import org.holoeverywhere.util.Pool;
+import org.holoeverywhere.util.Poolable;
+import org.holoeverywhere.util.PoolableManager;
+import org.holoeverywhere.util.Pools;
+import org.holoeverywhere.util.ReflectHelper;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ClipDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.StateListDrawable;
+import android.graphics.drawable.shapes.RoundRectShape;
+import android.graphics.drawable.shapes.Shape;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewDebug;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+import android.view.animation.Transformation;
+
+public class ProgressBar extends android.widget.ProgressBar {
+ private class AccessibilityEventSender implements Runnable {
+ @Override
+ public void run() {
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ }
+ }
+
+ private static class RefreshData implements Poolable<RefreshData> {
+ private static final int POOL_MAX = 24;
+ private static final Pool<RefreshData> sPool = Pools
+ .synchronizedPool(Pools.finitePool(
+ new PoolableManager<RefreshData>() {
+ @Override
+ public RefreshData newInstance() {
+ return new RefreshData();
+ }
+
+ @Override
+ public void onAcquired(RefreshData element) {
+ }
+
+ @Override
+ public void onReleased(RefreshData element) {
+ }
+ }, RefreshData.POOL_MAX));
+
+ public static RefreshData obtain(int id, int progress, boolean fromUser) {
+ RefreshData rd = RefreshData.sPool.acquire();
+ rd.id = id;
+ rd.progress = progress;
+ rd.fromUser = fromUser;
+ return rd;
+ }
+
+ public boolean fromUser;
+ public int id;
+ private boolean mIsPooled;
+ private RefreshData mNext;
+
+ public int progress;
+
+ @Override
+ public RefreshData getNextPoolable() {
+ return mNext;
+ }
+
+ @Override
+ public boolean isPooled() {
+ return mIsPooled;
+ }
+
+ public void recycle() {
+ RefreshData.sPool.release(this);
+ }
+
+ @Override
+ public void setNextPoolable(RefreshData element) {
+ mNext = element;
+ }
+
+ @Override
+ public void setPooled(boolean isPooled) {
+ mIsPooled = isPooled;
+ }
+ }
+
+ private class RefreshProgressRunnable implements Runnable {
+ @Override
+ public void run() {
+ synchronized (ProgressBar.this) {
+ final int count = mRefreshData.size();
+ for (int i = 0; i < count; i++) {
+ final RefreshData rd = mRefreshData.get(i);
+ doRefreshProgress(rd.id, rd.progress, rd.fromUser, true);
+ rd.recycle();
+ }
+ mRefreshData.clear();
+ mRefreshIsPosted = false;
+ }
+ }
+ }
+
+ protected static class SavedState extends BaseSavedState {
+ public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
+ @Override
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ @Override
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ int progress;
+
+ int secondaryProgress;
+
+ protected SavedState(Parcel in) {
+ super(in);
+ progress = in.readInt();
+ secondaryProgress = in.readInt();
+ }
+
+ protected SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeInt(progress);
+ out.writeInt(secondaryProgress);
+ }
+ }
+
+ private static final int MAX_LEVEL = 10000;
+ private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200;
+ private AccessibilityEventSender mAccessibilityEventSender;
+ private AlphaAnimation mAnimation;
+ private boolean mAttached;
+ private int mBehavior;
+ private Drawable mCurrentDrawable;
+ private int mDuration;
+ private boolean mHasAnimation;
+ private boolean mIndeterminate;
+ private Drawable mIndeterminateDrawable;
+ private boolean mInDrawing;
+ private Interpolator mInterpolator;
+ private int mMax;
+ protected int mMinWidth, mMaxWidth, mMinHeight, mMaxHeight;
+ private boolean mNoInvalidate;
+ private boolean mOnlyIndeterminate;
+ private int mProgress;
+ private Drawable mProgressDrawable;
+ private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>();
+ private boolean mRefreshIsPosted;
+ private RefreshProgressRunnable mRefreshProgressRunnable;
+ private Bitmap mSampleTile;
+ private int mSecondaryProgress;
+ private boolean mShouldStartAnimationDrawable;
+ private Transformation mTransformation;
+ private long mUiThreadId;
+
+ public ProgressBar(Context context) {
+ this(context, null);
+ }
+
+ public ProgressBar(Context context, AttributeSet attrs) {
+ this(context, attrs, android.R.attr.progressBarStyle);
+ }
+
+ public ProgressBar(Context context, AttributeSet attrs, int defStyle) {
+ this(context, attrs, defStyle, R.style.Holo_ProgressBar);
+ }
+
+ public ProgressBar(Context context, AttributeSet attrs, int defStyle,
+ int styleRes) {
+ super(context, attrs, defStyle);
+ mUiThreadId = Thread.currentThread().getId();
+ initProgressBar();
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.ProgressBar, defStyle, styleRes);
+ mNoInvalidate = true;
+
+ Drawable drawable = a.getDrawable(R.styleable.ProgressBar_android_progressDrawable);
+ if (drawable != null) {
+ drawable = tileify(drawable, false);
+ setProgressDrawable(drawable);
+ }
+ mDuration = a.getInt(
+ R.styleable.ProgressBar_android_indeterminateDuration,
+ mDuration);
+ mMinWidth = a.getDimensionPixelSize(
+ R.styleable.ProgressBar_android_minWidth, mMinWidth);
+ mMaxWidth = a.getDimensionPixelSize(
+ R.styleable.ProgressBar_android_maxWidth, mMaxWidth);
+ mMinHeight = a.getDimensionPixelSize(
+ R.styleable.ProgressBar_android_minHeight, mMinHeight);
+ mMaxHeight = a.getDimensionPixelSize(
+ R.styleable.ProgressBar_android_maxHeight, mMaxHeight);
+ mBehavior = a.getInt(
+ R.styleable.ProgressBar_android_indeterminateBehavior,
+ mBehavior);
+ final int resID = a.getResourceId(
+ R.styleable.ProgressBar_android_interpolator,
+ android.R.anim.linear_interpolator);
+ if (resID > 0) {
+ setInterpolator(context, resID);
+ }
+ setMax(a.getInt(R.styleable.ProgressBar_android_max, mMax));
+ setProgress(a.getInt(R.styleable.ProgressBar_android_progress,
+ mProgress));
+ setSecondaryProgress(a.getInt(
+ R.styleable.ProgressBar_android_secondaryProgress,
+ mSecondaryProgress));
+ drawable = DrawableCompat.getDrawable(a,
+ R.styleable.ProgressBar_android_indeterminateDrawable);
+ if (drawable != null) {
+ drawable = tileifyIndeterminate(drawable);
+ setIndeterminateDrawable(drawable);
+ }
+ mOnlyIndeterminate = a.getBoolean(
+ R.styleable.ProgressBar_android_indeterminateOnly,
+ mOnlyIndeterminate);
+ mNoInvalidate = false;
+ setIndeterminate(mOnlyIndeterminate
+ || a.getBoolean(R.styleable.ProgressBar_android_indeterminate,
+ mIndeterminate));
+ a.recycle();
+ }
+
+ private synchronized void doRefreshProgress(int id, int progress,
+ boolean fromUser, boolean callBackToApp) {
+ float scale = mMax > 0 ? (float) progress / (float) mMax : 0;
+ final Drawable d = mCurrentDrawable;
+ if (d != null) {
+ Drawable progressDrawable = null;
+ if (d instanceof LayerDrawable) {
+ progressDrawable = ((LayerDrawable) d)
+ .findDrawableByLayerId(id);
+ }
+ final int level = (int) (scale * ProgressBar.MAX_LEVEL);
+ (progressDrawable != null ? progressDrawable : d).setLevel(level);
+ } else {
+ invalidate();
+ }
+ if (callBackToApp && id == R.id.progress) {
+ onProgressRefresh(scale, fromUser);
+ }
+ }
+
+ @Override
+ protected void drawableStateChanged() {
+ super.drawableStateChanged();
+ updateDrawableState();
+ }
+
+ protected Drawable getCurrentDrawable() {
+ return mCurrentDrawable;
+ }
+
+ private Shape getDrawableShape() {
+ final float[] roundedCorners = new float[] {
+ 5, 5, 5, 5, 5, 5, 5, 5
+ };
+ return new RoundRectShape(roundedCorners, null, null);
+ }
+
+ @Override
+ public Drawable getIndeterminateDrawable() {
+ return mIndeterminateDrawable;
+ }
+
+ @Override
+ public Interpolator getInterpolator() {
+ return mInterpolator;
+ }
+
+ @Override
+ @ViewDebug.ExportedProperty(category = "progress")
+ public synchronized int getMax() {
+ return mMax;
+ }
+
+ @Override
+ @ViewDebug.ExportedProperty(category = "progress")
+ public synchronized int getProgress() {
+ return mIndeterminate ? 0 : mProgress;
+ }
+
+ @Override
+ public Drawable getProgressDrawable() {
+ return mProgressDrawable;
+ }
+
+ public int getResolvedLayoutDirection() {
+ return 0;
+ }
+
+ public int getResolvedLayoutDirection(Drawable who) {
+ return who == mProgressDrawable || who == mIndeterminateDrawable ? getResolvedLayoutDirection()
+ : 0;
+ }
+
+ @Override
+ @ViewDebug.ExportedProperty(category = "progress")
+ public synchronized int getSecondaryProgress() {
+ return mIndeterminate ? 0 : mSecondaryProgress;
+ }
+
+ public synchronized final void incrementProgress(int diff) {
+ setProgress(mProgress + diff);
+ }
+
+ public synchronized final void incrementSecondaryProgress(int diff) {
+ setSecondaryProgress(mSecondaryProgress + diff);
+ }
+
+ private void initProgressBar() {
+ mMax = 100;
+ mProgress = 0;
+ mSecondaryProgress = 0;
+ mIndeterminate = false;
+ mOnlyIndeterminate = false;
+ mDuration = 4000;
+ mBehavior = Animation.RESTART;
+ mMinWidth = 24;
+ mMaxWidth = 48;
+ mMinHeight = 24;
+ mMaxHeight = 48;
+ }
+
+ @Override
+ public void invalidateDrawable(Drawable dr) {
+ if (!mInDrawing) {
+ if (verifyDrawable(dr)) {
+ final Rect dirty = dr.getBounds();
+ final int scrollX = getScrollX() + getPaddingLeft();
+ final int scrollY = getScrollY() + getPaddingTop();
+
+ invalidate(dirty.left + scrollX, dirty.top + scrollY,
+ dirty.right + scrollX, dirty.bottom + scrollY);
+ } else {
+ super.invalidateDrawable(dr);
+ }
+ }
+ }
+
+ @Override
+ @ViewDebug.ExportedProperty(category = "progress")
+ public synchronized boolean isIndeterminate() {
+ return mIndeterminate;
+ }
+
+ @SuppressLint("NewApi")
+ @Override
+ public void jumpDrawablesToCurrentState() {
+ super.jumpDrawablesToCurrentState();
+ if (mProgressDrawable != null) {
+ mProgressDrawable.jumpToCurrentState();
+ }
+ if (mIndeterminateDrawable != null) {
+ mIndeterminateDrawable.jumpToCurrentState();
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (mIndeterminate) {
+ startAnimation();
+ }
+ if (mRefreshData != null) {
+ synchronized (this) {
+ final int count = mRefreshData.size();
+ for (int i = 0; i < count; i++) {
+ final RefreshData rd = mRefreshData.get(i);
+ doRefreshProgress(rd.id, rd.progress, rd.fromUser, true);
+ rd.recycle();
+ }
+ mRefreshData.clear();
+ }
+ }
+ mAttached = true;
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (mIndeterminate) {
+ stopAnimation();
+ }
+ if (mRefreshProgressRunnable != null) {
+ removeCallbacks(mRefreshProgressRunnable);
+ }
+ if (mRefreshProgressRunnable != null && mRefreshIsPosted) {
+ removeCallbacks(mRefreshProgressRunnable);
+ }
+ if (mAccessibilityEventSender != null) {
+ removeCallbacks(mAccessibilityEventSender);
+ }
+ super.onDetachedFromWindow();
+ mAttached = false;
+ }
+
+ @Override
+ protected synchronized void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ Drawable d = mCurrentDrawable;
+ if (d != null) {
+ canvas.save();
+ canvas.translate(getPaddingLeft(), getPaddingTop());
+ long time = getDrawingTime();
+ if (mHasAnimation) {
+ mAnimation.getTransformation(time, mTransformation);
+ float scale = mTransformation.getAlpha();
+ try {
+ mInDrawing = true;
+ d.setLevel((int) (scale * ProgressBar.MAX_LEVEL));
+ } finally {
+ mInDrawing = false;
+ }
+ postInvalidate();
+ }
+ d.draw(canvas);
+ canvas.restore();
+ if (mShouldStartAnimationDrawable && d instanceof Animatable) {
+ ((Animatable) d).start();
+ mShouldStartAnimationDrawable = false;
+ }
+ }
+ }
+
+ @SuppressLint("NewApi")
+ @Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+ event.setClassName(ProgressBar.class.getName());
+ event.setItemCount(mMax);
+ event.setCurrentItemIndex(mProgress);
+ }
+
+ @Override
+ @SuppressLint("NewApi")
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setClassName(ProgressBar.class.getName());
+ }
+
+ @Override
+ protected synchronized void onMeasure(int widthMeasureSpec,
+ int heightMeasureSpec) {
+ Drawable d = mCurrentDrawable;
+ int dw = 0;
+ int dh = 0;
+ if (d != null) {
+ dw = Math
+ .max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth()));
+ dh = Math.max(mMinHeight,
+ Math.min(mMaxHeight, d.getIntrinsicHeight()));
+ }
+ updateDrawableState();
+ dw += getPaddingLeft() + getPaddingRight();
+ dh += getPaddingTop() + getPaddingBottom();
+ setMeasuredDimension(
+ _View.supportResolveSizeAndState(dw, widthMeasureSpec, 0),
+ _View.supportResolveSizeAndState(dh, heightMeasureSpec, 0));
+ }
+
+ protected void onProgressRefresh(float scale, boolean fromUser) {
+ try {
+ if (((AccessibilityManager) AccessibilityManager.class.getMethod(
+ "getInstance", Context.class).invoke(null, getContext()))
+ .isEnabled()) {
+ scheduleAccessibilityEventSender();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ SavedState ss = (SavedState) state;
+ super.onRestoreInstanceState(ss.getSuperState());
+ setProgress(ss.progress);
+ setSecondaryProgress(ss.secondaryProgress);
+ }
+
+ @Override
+ public Parcelable onSaveInstanceState() {
+ Parcelable superState = super.onSaveInstanceState();
+ SavedState ss = new SavedState(superState);
+ ss.progress = mProgress;
+ ss.secondaryProgress = mSecondaryProgress;
+ return ss;
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ updateDrawableBounds(w, h);
+ }
+
+ @Override
+ public void onVisibilityChanged(View changedView, int visibility) {
+ super.onVisibilityChanged(changedView, visibility);
+ if (mIndeterminate) {
+ if (visibility == android.view.View.GONE
+ || visibility == android.view.View.INVISIBLE) {
+ stopAnimation();
+ } else {
+ startAnimation();
+ }
+ }
+ }
+
+ @Override
+ public void postInvalidate() {
+ if (!mNoInvalidate) {
+ super.postInvalidate();
+ }
+ }
+
+ private synchronized void refreshProgress(int id, int progress,
+ boolean fromUser) {
+ if (mUiThreadId == Thread.currentThread().getId()) {
+ doRefreshProgress(id, progress, fromUser, true);
+ } else if (mRefreshData != null) {
+ if (mRefreshProgressRunnable == null) {
+ mRefreshProgressRunnable = new RefreshProgressRunnable();
+ }
+
+ final RefreshData rd = RefreshData.obtain(id, progress, fromUser);
+ mRefreshData.add(rd);
+ if (mAttached && !mRefreshIsPosted) {
+ post(mRefreshProgressRunnable);
+ mRefreshIsPosted = true;
+ }
+ }
+ }
+
+ private void scheduleAccessibilityEventSender() {
+ if (mAccessibilityEventSender == null) {
+ mAccessibilityEventSender = new AccessibilityEventSender();
+ } else {
+ removeCallbacks(mAccessibilityEventSender);
+ }
+ postDelayed(mAccessibilityEventSender,
+ ProgressBar.TIMEOUT_SEND_ACCESSIBILITY_EVENT);
+ }
+
+ @Override
+ public synchronized void setIndeterminate(boolean indeterminate) {
+ if ((!mOnlyIndeterminate || !mIndeterminate)
+ && indeterminate != mIndeterminate) {
+ mIndeterminate = indeterminate;
+
+ if (indeterminate) {
+ // swap between indeterminate and regular backgrounds
+ mCurrentDrawable = mIndeterminateDrawable;
+ startAnimation();
+ } else {
+ mCurrentDrawable = mProgressDrawable;
+ stopAnimation();
+ }
+ }
+ }
+
+ @Override
+ public void setIndeterminateDrawable(Drawable d) {
+ if (d != null) {
+ d.setCallback(this);
+ }
+ mIndeterminateDrawable = d;
+ if (mIndeterminate) {
+ mCurrentDrawable = d;
+ postInvalidate();
+ }
+ }
+
+ @Override
+ public void setInterpolator(Context context, int resID) {
+ setInterpolator(AnimationUtils.loadInterpolator(context, resID));
+ }
+
+ @Override
+ public void setInterpolator(Interpolator interpolator) {
+ mInterpolator = interpolator;
+ }
+
+ @Override
+ public synchronized void setMax(int max) {
+ if (max < 0) {
+ max = 0;
+ }
+ if (max != mMax) {
+ mMax = max;
+ postInvalidate();
+
+ if (mProgress > max) {
+ mProgress = max;
+ }
+ refreshProgress(R.id.progress, mProgress, false);
+ }
+ }
+
+ @Override
+ public synchronized void setProgress(int progress) {
+ setProgress(progress, false);
+ }
+
+ synchronized void setProgress(int progress, boolean fromUser) {
+ if (mIndeterminate) {
+ return;
+ }
+ if (progress < 0) {
+ progress = 0;
+ }
+ if (progress > mMax) {
+ progress = mMax;
+ }
+ if (progress != mProgress) {
+ mProgress = progress;
+ refreshProgress(R.id.progress, mProgress, fromUser);
+ }
+ }
+
+ @Override
+ public void setProgressDrawable(Drawable d) {
+ boolean needUpdate;
+ if (mProgressDrawable != null && d != mProgressDrawable) {
+ mProgressDrawable.setCallback(null);
+ needUpdate = true;
+ } else {
+ needUpdate = false;
+ }
+ if (d != null) {
+ d.setCallback(this);
+ int drawableHeight = d.getMinimumHeight();
+ if (mMaxHeight < drawableHeight) {
+ mMaxHeight = drawableHeight;
+ requestLayout();
+ }
+ }
+ mProgressDrawable = d;
+ if (!mIndeterminate) {
+ mCurrentDrawable = d;
+ postInvalidate();
+ }
+ if (needUpdate) {
+ updateDrawableBounds(getWidth(), getHeight());
+ updateDrawableState();
+ doRefreshProgress(R.id.progress, mProgress, false, false);
+ doRefreshProgress(R.id.secondaryProgress, mSecondaryProgress,
+ false, false);
+ }
+ }
+
+ @Override
+ public synchronized void setSecondaryProgress(int secondaryProgress) {
+ if (mIndeterminate) {
+ return;
+ }
+ if (secondaryProgress < 0) {
+ secondaryProgress = 0;
+ }
+ if (secondaryProgress > mMax) {
+ secondaryProgress = mMax;
+ }
+ if (secondaryProgress != mSecondaryProgress) {
+ mSecondaryProgress = secondaryProgress;
+ refreshProgress(R.id.secondaryProgress, mSecondaryProgress, false);
+ }
+ }
+
+ @Override
+ public void setVisibility(int v) {
+ if (getVisibility() != v) {
+ super.setVisibility(v);
+ if (mIndeterminate) {
+ if (v == android.view.View.GONE
+ || v == android.view.View.INVISIBLE) {
+ stopAnimation();
+ } else {
+ startAnimation();
+ }
+ }
+ }
+ }
+
+ void startAnimation() {
+ if (getVisibility() != android.view.View.VISIBLE) {
+ return;
+ }
+ if (mIndeterminateDrawable instanceof Animatable) {
+ mShouldStartAnimationDrawable = true;
+ mHasAnimation = false;
+ } else {
+ mHasAnimation = true;
+ if (mInterpolator == null) {
+ mInterpolator = new LinearInterpolator();
+ }
+ if (mTransformation == null) {
+ mTransformation = new Transformation();
+ } else {
+ mTransformation.clear();
+ }
+ if (mAnimation == null) {
+ mAnimation = new AlphaAnimation(0.0f, 1.0f);
+ } else {
+ mAnimation.reset();
+ }
+ mAnimation.setRepeatMode(mBehavior);
+ mAnimation.setRepeatCount(Animation.INFINITE);
+ mAnimation.setDuration(mDuration);
+ mAnimation.setInterpolator(mInterpolator);
+ mAnimation.setStartTime(Animation.START_ON_FIRST_FRAME);
+ }
+ postInvalidate();
+ }
+
+ void stopAnimation() {
+ mHasAnimation = false;
+ if (mIndeterminateDrawable instanceof Animatable) {
+ ((Animatable) mIndeterminateDrawable).stop();
+ mShouldStartAnimationDrawable = false;
+ }
+ postInvalidate();
+ }
+
+ private Drawable tileify(Drawable drawable, boolean clip) {
+ if (drawable instanceof LayerDrawable) {
+ LayerDrawable background = (LayerDrawable) drawable;
+ final int N = background.getNumberOfLayers();
+ Drawable[] outDrawables = new Drawable[N];
+ for (int i = 0; i < N; i++) {
+ int id = background.getId(i);
+ outDrawables[i] = tileify(background.getDrawable(i),
+ id == R.id.progress || id == R.id.secondaryProgress);
+ }
+ LayerDrawable newBg = new LayerDrawable(outDrawables);
+ for (int i = 0; i < N; i++) {
+ newBg.setId(i, background.getId(i));
+ }
+ return newBg;
+ } else if (drawable instanceof StateListDrawable) {
+ StateListDrawable in = (StateListDrawable) drawable;
+ StateListDrawable out = new StateListDrawable();
+ int numStates = ReflectHelper
+ .invoke(in, "getStateCount", int.class);
+ for (int i = 0; i < numStates; i++) {
+ out.addState(
+ ReflectHelper.invoke(in, "getStateSet", int[].class, i),
+ tileify(ReflectHelper.invoke(in, "getStateDrawable",
+ Drawable.class, i), clip));
+ }
+ return out;
+ } else if (drawable instanceof BitmapDrawable) {
+ final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap();
+ if (mSampleTile == null) {
+ mSampleTile = tileBitmap;
+ }
+ final ShapeDrawable shapeDrawable = new ShapeDrawable(
+ getDrawableShape());
+ final BitmapShader bitmapShader = new BitmapShader(tileBitmap,
+ Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
+ shapeDrawable.getPaint().setShader(bitmapShader);
+ return clip ? new ClipDrawable(shapeDrawable, Gravity.LEFT,
+ ClipDrawable.HORIZONTAL) : shapeDrawable;
+ }
+ return drawable;
+ }
+
+ private Drawable tileifyIndeterminate(Drawable drawable) {
+ if (drawable instanceof AnimationDrawable) {
+ AnimationDrawable background = (AnimationDrawable) drawable;
+ final int N = background.getNumberOfFrames();
+ AnimationDrawable newBg = new AnimationDrawable();
+ newBg.setOneShot(background.isOneShot());
+ for (int i = 0; i < N; i++) {
+ Drawable frame = tileify(background.getFrame(i), true);
+ frame.setLevel(10000);
+ newBg.addFrame(frame, background.getDuration(i));
+ }
+ newBg.setLevel(10000);
+ drawable = newBg;
+ }
+ return drawable;
+ }
+
+ private void updateDrawableBounds(int w, int h) {
+ int right = w - getPaddingRight() - getPaddingLeft();
+ int bottom = h - getPaddingBottom() - getPaddingTop();
+ int top = 0;
+ int left = 0;
+ if (mIndeterminateDrawable != null) {
+ if (mOnlyIndeterminate
+ && !(mIndeterminateDrawable instanceof AnimationDrawable)) {
+ final int intrinsicWidth = mIndeterminateDrawable
+ .getIntrinsicWidth();
+ final int intrinsicHeight = mIndeterminateDrawable
+ .getIntrinsicHeight();
+ final float intrinsicAspect = (float) intrinsicWidth
+ / intrinsicHeight;
+ final float boundAspect = (float) w / h;
+ if (intrinsicAspect != boundAspect) {
+ if (boundAspect > intrinsicAspect) {
+ final int width = (int) (h * intrinsicAspect);
+ left = (w - width) / 2;
+ right = left + width;
+ } else {
+ final int height = (int) (w * (1 / intrinsicAspect));
+ top = (h - height) / 2;
+ bottom = top + height;
+ }
+ }
+ }
+ mIndeterminateDrawable.setBounds(left, top, right, bottom);
+ }
+ if (mProgressDrawable != null) {
+ mProgressDrawable.setBounds(0, 0, right, bottom);
+ }
+ }
+
+ private void updateDrawableState() {
+ int[] state = getDrawableState();
+ if (mProgressDrawable != null && mProgressDrawable.isStateful()) {
+ mProgressDrawable.setState(state);
+ }
+ if (mIndeterminateDrawable != null
+ && mIndeterminateDrawable.isStateful()) {
+ mIndeterminateDrawable.setState(state);
+ }
+ }
+
+ @Override
+ protected boolean verifyDrawable(Drawable who) {
+ return who == mProgressDrawable || who == mIndeterminateDrawable
+ || super.verifyDrawable(who);
+ }
+}