1f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen/* 2f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Copyright (C) 2006 The Android Open Source Project 3f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 4f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Licensed under the Apache License, Version 2.0 (the "License"); 5f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * you may not use this file except in compliance with the License. 6f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * You may obtain a copy of the License at 7f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 8f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * http://www.apache.org/licenses/LICENSE-2.0 9f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 10f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Unless required by applicable law or agreed to in writing, software 11f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * distributed under the License is distributed on an "AS IS" BASIS, 12f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * See the License for the specific language governing permissions and 14f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * limitations under the License. 15f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 16f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 17f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenpackage com.android.musicfx.seekbar; 18f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 19f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport com.android.internal.R; 20f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 21f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.content.Context; 22f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.content.res.TypedArray; 23f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.Bitmap; 24f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.BitmapShader; 25f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.Canvas; 26f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.Rect; 27f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.Shader; 28f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.drawable.Animatable; 29f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.drawable.AnimationDrawable; 30f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.drawable.BitmapDrawable; 31f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.drawable.ClipDrawable; 32f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.drawable.Drawable; 33f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.drawable.LayerDrawable; 34f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.drawable.ShapeDrawable; 35f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.drawable.StateListDrawable; 36f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.drawable.shapes.RoundRectShape; 37f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.drawable.shapes.Shape; 38f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.os.Parcel; 39f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.os.Parcelable; 40f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.os.SystemClock; 41f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.util.AttributeSet; 42f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.Gravity; 43f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.RemotableViewMethod; 44f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.View; 45f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.ViewDebug; 46f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.accessibility.AccessibilityEvent; 47f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.accessibility.AccessibilityManager; 48f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.animation.AlphaAnimation; 49f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.animation.Animation; 50f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.animation.AnimationUtils; 51f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.animation.Interpolator; 52f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.animation.LinearInterpolator; 53f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.animation.Transformation; 54f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.widget.RemoteViews.RemoteView; 55f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 56f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 57f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen/** 58f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p> 59f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Visual indicator of progress in some operation. Displays a bar to the user 60f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * representing how far the operation has progressed; the application can 61f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * change the amount of progress (modifying the length of the bar) as it moves 62f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * forward. There is also a secondary progress displayable on a progress bar 63f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * which is useful for displaying intermediate progress, such as the buffer 64f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * level during a streaming playback progress bar. 65f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * </p> 66f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 67f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p> 68f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * A progress bar can also be made indeterminate. In indeterminate mode, the 69f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * progress bar shows a cyclic animation without an indication of progress. This mode is used by 70f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * applications when the length of the task is unknown. The indeterminate progress bar can be either 71f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * a spinning wheel or a horizontal bar. 72f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * </p> 73f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 74f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>The following code example shows how a progress bar can be used from 75f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * a worker thread to update the user interface to notify the user of progress: 76f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * </p> 77f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 78f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <pre> 79f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * public class MyActivity extends Activity { 80f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * private static final int PROGRESS = 0x1; 81f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 82f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * private ProgressBar mProgress; 83f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * private int mProgressStatus = 0; 84f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 85f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * private Handler mHandler = new Handler(); 86f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 87f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * protected void onCreate(Bundle icicle) { 88f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * super.onCreate(icicle); 89f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 90f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * setContentView(R.layout.progressbar_activity); 91f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 92f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * mProgress = (ProgressBar) findViewById(R.id.progress_bar); 93f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 94f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * // Start lengthy operation in a background thread 95f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * new Thread(new Runnable() { 96f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * public void run() { 97f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * while (mProgressStatus < 100) { 98f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * mProgressStatus = doWork(); 99f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 100f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * // Update the progress bar 101f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * mHandler.post(new Runnable() { 102f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * public void run() { 103f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * mProgress.setProgress(mProgressStatus); 104f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * } 105f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * }); 106f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * } 107f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * } 108f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * }).start(); 109f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * } 110f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * }</pre> 111f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 112f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>To add a progress bar to a layout file, you can use the {@code <ProgressBar>} element. 113f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * By default, the progress bar is a spinning wheel (an indeterminate indicator). To change to a 114f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * horizontal progress bar, apply the {@link android.R.style#Widget_ProgressBar_Horizontal 115f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Widget.ProgressBar.Horizontal} style, like so:</p> 116f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 117f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <pre> 118f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <ProgressBar 119f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * style="@android:style/Widget.ProgressBar.Horizontal" 120f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * ... /></pre> 121f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 122f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>If you will use the progress bar to show real progress, you must use the horizontal bar. You 123f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * can then increment the progress with {@link #incrementProgressBy incrementProgressBy()} or 124f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * {@link #setProgress setProgress()}. By default, the progress bar is full when it reaches 100. If 125f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * necessary, you can adjust the maximum value (the value for a full bar) using the {@link 126f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * android.R.styleable#ProgressBar_max android:max} attribute. Other attributes available are listed 127f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * below.</p> 128f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 129f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Another common style to apply to the progress bar is {@link 130f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}, which shows a smaller 131f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * version of the spinning wheel—useful when waiting for content to load. 132f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * For example, you can insert this kind of progress bar into your default layout for 133f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * a view that will be populated by some content fetched from the Internet—the spinning wheel 134f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * appears immediately and when your application receives the content, it replaces the progress bar 135f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * with the loaded content. For example:</p> 136f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 137f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <pre> 138f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <LinearLayout 139f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * android:orientation="horizontal" 140f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * ... > 141f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <ProgressBar 142f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * android:layout_width="wrap_content" 143f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * android:layout_height="wrap_content" 144f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * style="@android:style/Widget.ProgressBar.Small" 145f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * android:layout_marginRight="5dp" /> 146f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <TextView 147f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * android:layout_width="wrap_content" 148f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * android:layout_height="wrap_content" 149f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * android:text="@string/loading" /> 150f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * </LinearLayout></pre> 151f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 152f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Other progress bar styles provided by the system include:</p> 153f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <ul> 154f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <li>{@link android.R.style#Widget_ProgressBar_Horizontal Widget.ProgressBar.Horizontal}</li> 155f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <li>{@link android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}</li> 156f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <li>{@link android.R.style#Widget_ProgressBar_Large Widget.ProgressBar.Large}</li> 157f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <li>{@link android.R.style#Widget_ProgressBar_Inverse Widget.ProgressBar.Inverse}</li> 158f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <li>{@link android.R.style#Widget_ProgressBar_Small_Inverse 159f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Widget.ProgressBar.Small.Inverse}</li> 160f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <li>{@link android.R.style#Widget_ProgressBar_Large_Inverse 161f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Widget.ProgressBar.Large.Inverse}</li> 162f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * </ul> 163f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>The "inverse" styles provide an inverse color scheme for the spinner, which may be necessary 164f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * if your application uses a light colored theme (a white background).</p> 165f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 166f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p><strong>XML attributes</b></strong> 167f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p> 168f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * See {@link android.R.styleable#ProgressBar ProgressBar Attributes}, 169f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * {@link android.R.styleable#View View Attributes} 170f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * </p> 171f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 172f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_animationResolution 173f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_indeterminate 174f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_indeterminateBehavior 175f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_indeterminateDrawable 176f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_indeterminateDuration 177f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_indeterminateOnly 178f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_interpolator 179f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_max 180f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_maxHeight 181f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_maxWidth 182f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_minHeight 183f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_minWidth 184f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_progress 185f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_progressDrawable 186f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @attr ref android.R.styleable#ProgressBar_secondaryProgress 187f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 188f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen@RemoteView 189f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenpublic class ProgressBar extends View { 190f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private static final int MAX_LEVEL = 10000; 191f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private static final int ANIMATION_RESOLUTION = 200; 192f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200; 193f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 194f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int mMinWidth; 195f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int mMaxWidth; 196f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int mMinHeight; 197f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int mMaxHeight; 198f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 199f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private int mProgress; 200f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private int mSecondaryProgress; 201f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private int mMax; 202f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 203f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private int mBehavior; 204f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private int mDuration; 205f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private boolean mIndeterminate; 206f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private boolean mOnlyIndeterminate; 207f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private Transformation mTransformation; 208f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private AlphaAnimation mAnimation; 209f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private Drawable mIndeterminateDrawable; 210f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private Drawable mProgressDrawable; 211f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private Drawable mCurrentDrawable; 212f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Bitmap mSampleTile; 213f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private boolean mNoInvalidate; 214f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private Interpolator mInterpolator; 215f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private RefreshProgressRunnable mRefreshProgressRunnable; 216f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private long mUiThreadId; 217f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private boolean mShouldStartAnimationDrawable; 218f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private long mLastDrawTime; 219f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 220f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private boolean mInDrawing; 221f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 222f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private int mAnimationResolution; 223f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 224f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private AccessibilityEventSender mAccessibilityEventSender; 225f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 226f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 227f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Create a new progress bar with range 0...100 and initial progress of 0. 228f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param context the application environment 229f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 230f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public ProgressBar(Context context) { 231f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen this(context, null); 232f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 233f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 234f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public ProgressBar(Context context, AttributeSet attrs) { 235f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen this(context, attrs, com.android.internal.R.attr.progressBarStyle); 236f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 237f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 238f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public ProgressBar(Context context, AttributeSet attrs, int defStyle) { 239f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen this(context, attrs, defStyle, 0); 240f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 241f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 242f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 243f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @hide 244f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 245f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public ProgressBar(Context context, AttributeSet attrs, int defStyle, int styleRes) { 246f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super(context, attrs, defStyle); 247f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mUiThreadId = Thread.currentThread().getId(); 248f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen initProgressBar(); 249f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 250f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen TypedArray a = 251f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen context.obtainStyledAttributes(attrs, R.styleable.ProgressBar, defStyle, styleRes); 252f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 253f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mNoInvalidate = true; 254f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 255f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable drawable = a.getDrawable(R.styleable.ProgressBar_progressDrawable); 256f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (drawable != null) { 257f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen drawable = tileify(drawable, false); 258f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // Calling this method can set mMaxHeight, make sure the corresponding 259f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // XML attribute for mMaxHeight is read after calling this method 260f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setProgressDrawable(drawable); 261f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 262f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 263f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 264f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mDuration = a.getInt(R.styleable.ProgressBar_indeterminateDuration, mDuration); 265f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 266f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mMinWidth = a.getDimensionPixelSize(R.styleable.ProgressBar_minWidth, mMinWidth); 267f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mMaxWidth = a.getDimensionPixelSize(R.styleable.ProgressBar_maxWidth, mMaxWidth); 268f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mMinHeight = a.getDimensionPixelSize(R.styleable.ProgressBar_minHeight, mMinHeight); 269f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mMaxHeight = a.getDimensionPixelSize(R.styleable.ProgressBar_maxHeight, mMaxHeight); 270f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 271f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mBehavior = a.getInt(R.styleable.ProgressBar_indeterminateBehavior, mBehavior); 272f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 273f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final int resID = a.getResourceId( 274f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen com.android.internal.R.styleable.ProgressBar_interpolator, 275f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen android.R.anim.linear_interpolator); // default to linear interpolator 276f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (resID > 0) { 277f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setInterpolator(context, resID); 278f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 279f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 280f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setMax(a.getInt(R.styleable.ProgressBar_max, mMax)); 281f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 282f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setProgress(a.getInt(R.styleable.ProgressBar_progress, mProgress)); 283f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 284f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setSecondaryProgress( 285f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen a.getInt(R.styleable.ProgressBar_secondaryProgress, mSecondaryProgress)); 286f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 287f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen drawable = a.getDrawable(R.styleable.ProgressBar_indeterminateDrawable); 288f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (drawable != null) { 289f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen drawable = tileifyIndeterminate(drawable); 290f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setIndeterminateDrawable(drawable); 291f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 292f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 293f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mOnlyIndeterminate = a.getBoolean( 294f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen R.styleable.ProgressBar_indeterminateOnly, mOnlyIndeterminate); 295f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 296f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mNoInvalidate = false; 297f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 298f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setIndeterminate(mOnlyIndeterminate || a.getBoolean( 299f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen R.styleable.ProgressBar_indeterminate, mIndeterminate)); 300f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 301f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mAnimationResolution = a.getInteger(R.styleable.ProgressBar_animationResolution, 302f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen ANIMATION_RESOLUTION); 303f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 304f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen a.recycle(); 305f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 306f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 307f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 308f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Converts a drawable to a tiled version of itself. It will recursively 309f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * traverse layer and state list drawables. 310f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 311f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private Drawable tileify(Drawable drawable, boolean clip) { 312f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 313f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (drawable instanceof LayerDrawable) { 314f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen LayerDrawable background = (LayerDrawable) drawable; 315f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final int N = background.getNumberOfLayers(); 316f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable[] outDrawables = new Drawable[N]; 317f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 318f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen for (int i = 0; i < N; i++) { 319f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int id = background.getId(i); 320f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen outDrawables[i] = tileify(background.getDrawable(i), 321f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen (id == R.id.progress || id == R.id.secondaryProgress)); 322f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 323f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 324f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen LayerDrawable newBg = new LayerDrawable(outDrawables); 325f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 326f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen for (int i = 0; i < N; i++) { 327f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen newBg.setId(i, background.getId(i)); 328f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 329f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 330f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return newBg; 331f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 332f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else if (drawable instanceof StateListDrawable) { 333f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen StateListDrawable in = (StateListDrawable) drawable; 334f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen StateListDrawable out = new StateListDrawable(); 335f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int numStates = in.getStateCount(); 336f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen for (int i = 0; i < numStates; i++) { 337f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen out.addState(in.getStateSet(i), tileify(in.getStateDrawable(i), clip)); 338f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 339f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return out; 340f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 341f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else if (drawable instanceof BitmapDrawable) { 342f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap(); 343f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mSampleTile == null) { 344f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mSampleTile = tileBitmap; 345f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 346f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 347f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape()); 348f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 349f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final BitmapShader bitmapShader = new BitmapShader(tileBitmap, 350f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); 351f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen shapeDrawable.getPaint().setShader(bitmapShader); 352f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 353f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT, 354f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen ClipDrawable.HORIZONTAL) : shapeDrawable; 355f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 356f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 357f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return drawable; 358f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 359f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 360f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Shape getDrawableShape() { 361f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 }; 362f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return new RoundRectShape(roundedCorners, null, null); 363f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 364f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 365f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 366f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Convert a AnimationDrawable for use as a barberpole animation. 367f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Each frame of the animation is wrapped in a ClipDrawable and 368f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * given a tiling BitmapShader. 369f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 370f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private Drawable tileifyIndeterminate(Drawable drawable) { 371f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (drawable instanceof AnimationDrawable) { 372f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen AnimationDrawable background = (AnimationDrawable) drawable; 373f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final int N = background.getNumberOfFrames(); 374f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen AnimationDrawable newBg = new AnimationDrawable(); 375f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen newBg.setOneShot(background.isOneShot()); 376f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 377f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen for (int i = 0; i < N; i++) { 378f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable frame = tileify(background.getFrame(i), true); 379f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen frame.setLevel(10000); 380f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen newBg.addFrame(frame, background.getDuration(i)); 381f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 382f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen newBg.setLevel(10000); 383f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen drawable = newBg; 384f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 385f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return drawable; 386f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 387f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 388f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 389f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p> 390f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Initialize the progress bar's default values: 391f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * </p> 392f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <ul> 393f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <li>progress = 0</li> 394f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <li>max = 100</li> 395f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <li>animation duration = 4000 ms</li> 396f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <li>indeterminate = false</li> 397f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <li>behavior = repeat</li> 398f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * </ul> 399f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 400f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private void initProgressBar() { 401f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mMax = 100; 402f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mProgress = 0; 403f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mSecondaryProgress = 0; 404f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mIndeterminate = false; 405f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mOnlyIndeterminate = false; 406f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mDuration = 4000; 407f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mBehavior = AlphaAnimation.RESTART; 408f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mMinWidth = 24; 409f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mMaxWidth = 48; 410f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mMinHeight = 24; 411f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mMaxHeight = 48; 412f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 413f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 414f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 415f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Indicate whether this progress bar is in indeterminate mode.</p> 416f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 417f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @return true if the progress bar is in indeterminate mode 418f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 419f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @ViewDebug.ExportedProperty(category = "progress") 420f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public synchronized boolean isIndeterminate() { 421f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return mIndeterminate; 422f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 423f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 424f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 425f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Change the indeterminate mode for this progress bar. In indeterminate 426f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * mode, the progress is ignored and the progress bar shows an infinite 427f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * animation instead.</p> 428f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 429f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * If this progress bar's style only supports indeterminate mode (such as the circular 430f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * progress bars), then this will be ignored. 431f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 432f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param indeterminate true to enable the indeterminate mode 433f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 434f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @android.view.RemotableViewMethod 435f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public synchronized void setIndeterminate(boolean indeterminate) { 436f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) { 437f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mIndeterminate = indeterminate; 438f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 439f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (indeterminate) { 440f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // swap between indeterminate and regular backgrounds 441f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mCurrentDrawable = mIndeterminateDrawable; 442f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen startAnimation(); 443f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 444f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mCurrentDrawable = mProgressDrawable; 445f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen stopAnimation(); 446f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 447f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 448f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 449f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 450f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 451f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Get the drawable used to draw the progress bar in 452f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * indeterminate mode.</p> 453f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 454f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @return a {@link android.graphics.drawable.Drawable} instance 455f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 456f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setIndeterminateDrawable(android.graphics.drawable.Drawable) 457f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setIndeterminate(boolean) 458f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 459f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public Drawable getIndeterminateDrawable() { 460f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return mIndeterminateDrawable; 461f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 462f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 463f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 464f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Define the drawable used to draw the progress bar in 465f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * indeterminate mode.</p> 466f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 467f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param d the new drawable 468f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 469f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #getIndeterminateDrawable() 470f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setIndeterminate(boolean) 471f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 472f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void setIndeterminateDrawable(Drawable d) { 473f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (d != null) { 474f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen d.setCallback(this); 475f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 476f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mIndeterminateDrawable = d; 477f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminate) { 478f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mCurrentDrawable = d; 479f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen postInvalidate(); 480f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 481f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 482f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 483f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 484f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Get the drawable used to draw the progress bar in 485f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * progress mode.</p> 486f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 487f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @return a {@link android.graphics.drawable.Drawable} instance 488f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 489f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setProgressDrawable(android.graphics.drawable.Drawable) 490f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setIndeterminate(boolean) 491f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 492f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public Drawable getProgressDrawable() { 493f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return mProgressDrawable; 494f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 495f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 496f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 497f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Define the drawable used to draw the progress bar in 498f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * progress mode.</p> 499f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 500f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param d the new drawable 501f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 502f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #getProgressDrawable() 503f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setIndeterminate(boolean) 504f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 505f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void setProgressDrawable(Drawable d) { 506f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen boolean needUpdate; 507f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mProgressDrawable != null && d != mProgressDrawable) { 508f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mProgressDrawable.setCallback(null); 509f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen needUpdate = true; 510f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 511f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen needUpdate = false; 512f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 513f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 514f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (d != null) { 515f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen d.setCallback(this); 516f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 517f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // Make sure the ProgressBar is always tall enough 518f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int drawableHeight = d.getMinimumHeight(); 519f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mMaxHeight < drawableHeight) { 520f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mMaxHeight = drawableHeight; 521f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen requestLayout(); 522f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 523f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 524f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mProgressDrawable = d; 525f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (!mIndeterminate) { 526f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mCurrentDrawable = d; 527f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen postInvalidate(); 528f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 529f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 530f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (needUpdate) { 531f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen updateDrawableBounds(getWidth(), getHeight()); 532f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen updateDrawableState(); 533f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen doRefreshProgress(R.id.progress, mProgress, false, false); 534f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen doRefreshProgress(R.id.secondaryProgress, mSecondaryProgress, false, false); 535f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 536f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 537f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 538f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 539f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @return The drawable currently used to draw the progress bar 540f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 541f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable getCurrentDrawable() { 542f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return mCurrentDrawable; 543f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 544f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 545f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 546f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected boolean verifyDrawable(Drawable who) { 547f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return who == mProgressDrawable || who == mIndeterminateDrawable 548f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen || super.verifyDrawable(who); 549f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 550f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 551f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 552f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void jumpDrawablesToCurrentState() { 553f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.jumpDrawablesToCurrentState(); 554f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mProgressDrawable != null) mProgressDrawable.jumpToCurrentState(); 555f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminateDrawable != null) mIndeterminateDrawable.jumpToCurrentState(); 556f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 557f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 558f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 559f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void postInvalidate() { 560f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (!mNoInvalidate) { 561f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.postInvalidate(); 562f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 563f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 564f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 565f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private class RefreshProgressRunnable implements Runnable { 566f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 567f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private int mId; 568f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private int mProgress; 569f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private boolean mFromUser; 570f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 571f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen RefreshProgressRunnable(int id, int progress, boolean fromUser) { 572f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mId = id; 573f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mProgress = progress; 574f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mFromUser = fromUser; 575f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 576f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 577f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void run() { 578f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen doRefreshProgress(mId, mProgress, mFromUser, true); 579f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // Put ourselves back in the cache when we are done 580f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mRefreshProgressRunnable = this; 581f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 582f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 583f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void setup(int id, int progress, boolean fromUser) { 584f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mId = id; 585f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mProgress = progress; 586f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mFromUser = fromUser; 587f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 588f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 589f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 590f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 591f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private synchronized void doRefreshProgress(int id, int progress, boolean fromUser, 592f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen boolean callBackToApp) { 593f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen float scale = mMax > 0 ? (float) progress / (float) mMax : 0; 594f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final Drawable d = mCurrentDrawable; 595f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (d != null) { 596f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable progressDrawable = null; 597f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 598f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (d instanceof LayerDrawable) { 599f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen progressDrawable = ((LayerDrawable) d).findDrawableByLayerId(id); 600f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 601f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 602f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final int level = (int) (scale * MAX_LEVEL); 603f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen (progressDrawable != null ? progressDrawable : d).setLevel(level); 604f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 605f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen invalidate(); 606f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 607f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 608f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (callBackToApp && id == R.id.progress) { 609f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen onProgressRefresh(scale, fromUser); 610f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 611f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 612f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 613f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen void onProgressRefresh(float scale, boolean fromUser) { 614f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (AccessibilityManager.getInstance(mContext).isEnabled()) { 615f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen scheduleAccessibilityEventSender(); 616f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 617f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 618f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 619f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private synchronized void refreshProgress(int id, int progress, boolean fromUser) { 620f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mUiThreadId == Thread.currentThread().getId()) { 621f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen doRefreshProgress(id, progress, fromUser, true); 622f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 623f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen RefreshProgressRunnable r; 624f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mRefreshProgressRunnable != null) { 625f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // Use cached RefreshProgressRunnable if available 626f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen r = mRefreshProgressRunnable; 627f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // Uncache it 628f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mRefreshProgressRunnable = null; 629f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen r.setup(id, progress, fromUser); 630f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 631f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // Make a new one 632f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen r = new RefreshProgressRunnable(id, progress, fromUser); 633f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 634f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen post(r); 635f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 636f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 637f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 638f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 639f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Set the current progress to the specified value. Does not do anything 640f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * if the progress bar is in indeterminate mode.</p> 641f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 642f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param progress the new progress, between 0 and {@link #getMax()} 643f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 644f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setIndeterminate(boolean) 645f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #isIndeterminate() 646f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #getProgress() 647f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #incrementProgressBy(int) 648f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 649f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @android.view.RemotableViewMethod 650f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public synchronized void setProgress(int progress) { 651f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setProgress(progress, false); 652f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 653f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 654f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @android.view.RemotableViewMethod 655f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen synchronized void setProgress(int progress, boolean fromUser) { 656f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminate) { 657f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return; 658f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 659f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 660f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (progress < 0) { 661f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen progress = 0; 662f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 663f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 664f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (progress > mMax) { 665f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen progress = mMax; 666f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 667f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 668f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (progress != mProgress) { 669f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mProgress = progress; 670f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen refreshProgress(R.id.progress, mProgress, fromUser); 671f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 672f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 673f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 674f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 675f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p> 676f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Set the current secondary progress to the specified value. Does not do 677f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * anything if the progress bar is in indeterminate mode. 678f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * </p> 679f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 680f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param secondaryProgress the new secondary progress, between 0 and {@link #getMax()} 681f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setIndeterminate(boolean) 682f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #isIndeterminate() 683f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #getSecondaryProgress() 684f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #incrementSecondaryProgressBy(int) 685f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 686f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @android.view.RemotableViewMethod 687f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public synchronized void setSecondaryProgress(int secondaryProgress) { 688f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminate) { 689f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return; 690f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 691f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 692f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (secondaryProgress < 0) { 693f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen secondaryProgress = 0; 694f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 695f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 696f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (secondaryProgress > mMax) { 697f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen secondaryProgress = mMax; 698f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 699f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 700f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (secondaryProgress != mSecondaryProgress) { 701f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mSecondaryProgress = secondaryProgress; 702f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen refreshProgress(R.id.secondaryProgress, mSecondaryProgress, false); 703f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 704f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 705f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 706f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 707f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Get the progress bar's current level of progress. Return 0 when the 708f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * progress bar is in indeterminate mode.</p> 709f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 710f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @return the current progress, between 0 and {@link #getMax()} 711f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 712f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setIndeterminate(boolean) 713f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #isIndeterminate() 714f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setProgress(int) 715f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setMax(int) 716f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #getMax() 717f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 718f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @ViewDebug.ExportedProperty(category = "progress") 719f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public synchronized int getProgress() { 720f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return mIndeterminate ? 0 : mProgress; 721f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 722f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 723f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 724f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Get the progress bar's current level of secondary progress. Return 0 when the 725f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * progress bar is in indeterminate mode.</p> 726f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 727f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @return the current secondary progress, between 0 and {@link #getMax()} 728f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 729f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setIndeterminate(boolean) 730f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #isIndeterminate() 731f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setSecondaryProgress(int) 732f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setMax(int) 733f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #getMax() 734f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 735f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @ViewDebug.ExportedProperty(category = "progress") 736f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public synchronized int getSecondaryProgress() { 737f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return mIndeterminate ? 0 : mSecondaryProgress; 738f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 739f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 740f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 741f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Return the upper limit of this progress bar's range.</p> 742f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 743f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @return a positive integer 744f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 745f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setMax(int) 746f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #getProgress() 747f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #getSecondaryProgress() 748f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 749f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @ViewDebug.ExportedProperty(category = "progress") 750f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public synchronized int getMax() { 751f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return mMax; 752f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 753f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 754f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 755f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Set the range of the progress bar to 0...<tt>max</tt>.</p> 756f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 757f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param max the upper range of this progress bar 758f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 759f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #getMax() 760f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setProgress(int) 761f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setSecondaryProgress(int) 762f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 763f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @android.view.RemotableViewMethod 764f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public synchronized void setMax(int max) { 765f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (max < 0) { 766f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen max = 0; 767f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 768f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (max != mMax) { 769f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mMax = max; 770f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen postInvalidate(); 771f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 772f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mProgress > max) { 773f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mProgress = max; 774f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 775f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen refreshProgress(R.id.progress, mProgress, false); 776f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 777f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 778f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 779f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 780f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Increase the progress bar's progress by the specified amount.</p> 781f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 782f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param diff the amount by which the progress must be increased 783f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 784f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setProgress(int) 785f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 786f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public synchronized final void incrementProgressBy(int diff) { 787f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setProgress(mProgress + diff); 788f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 789f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 790f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 791f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Increase the progress bar's secondary progress by the specified amount.</p> 792f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 793f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param diff the amount by which the secondary progress must be increased 794f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 795f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setSecondaryProgress(int) 796f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 797f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public synchronized final void incrementSecondaryProgressBy(int diff) { 798f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setSecondaryProgress(mSecondaryProgress + diff); 799f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 800f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 801f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 802f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Start the indeterminate progress animation.</p> 803f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 804f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen void startAnimation() { 805f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (getVisibility() != VISIBLE) { 806f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return; 807f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 808f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 809f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminateDrawable instanceof Animatable) { 810f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mShouldStartAnimationDrawable = true; 811f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mAnimation = null; 812f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 813f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mInterpolator == null) { 814f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mInterpolator = new LinearInterpolator(); 815f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 816f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 817f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mTransformation = new Transformation(); 818f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mAnimation = new AlphaAnimation(0.0f, 1.0f); 819f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mAnimation.setRepeatMode(mBehavior); 820f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mAnimation.setRepeatCount(Animation.INFINITE); 821f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mAnimation.setDuration(mDuration); 822f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mAnimation.setInterpolator(mInterpolator); 823f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mAnimation.setStartTime(Animation.START_ON_FIRST_FRAME); 824f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 825f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen postInvalidate(); 826f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 827f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 828f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 829f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p>Stop the indeterminate progress animation.</p> 830f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 831f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen void stopAnimation() { 832f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mAnimation = null; 833f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mTransformation = null; 834f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminateDrawable instanceof Animatable) { 835f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen ((Animatable) mIndeterminateDrawable).stop(); 836f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mShouldStartAnimationDrawable = false; 837f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 838f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen postInvalidate(); 839f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 840f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 841f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 842f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Sets the acceleration curve for the indeterminate animation. 843f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * The interpolator is loaded as a resource from the specified context. 844f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 845f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param context The application environment 846f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param resID The resource identifier of the interpolator to load 847f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 848f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void setInterpolator(Context context, int resID) { 849f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setInterpolator(AnimationUtils.loadInterpolator(context, resID)); 850f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 851f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 852f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 853f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Sets the acceleration curve for the indeterminate animation. 854f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Defaults to a linear interpolation. 855f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 856f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param interpolator The interpolator which defines the acceleration curve 857f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 858f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void setInterpolator(Interpolator interpolator) { 859f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mInterpolator = interpolator; 860f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 861f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 862f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 863f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Gets the acceleration curve type for the indeterminate animation. 864f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 865f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @return the {@link Interpolator} associated to this animation 866f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 867f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public Interpolator getInterpolator() { 868f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return mInterpolator; 869f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 870f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 871f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 872f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @RemotableViewMethod 873f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void setVisibility(int v) { 874f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (getVisibility() != v) { 875f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.setVisibility(v); 876f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 877f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminate) { 878f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // let's be nice with the UI thread 879f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (v == GONE || v == INVISIBLE) { 880f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen stopAnimation(); 881f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 882f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen startAnimation(); 883f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 884f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 885f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 886f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 887f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 888f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 889f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected void onVisibilityChanged(View changedView, int visibility) { 890f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.onVisibilityChanged(changedView, visibility); 891f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 892f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminate) { 893f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // let's be nice with the UI thread 894f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (visibility == GONE || visibility == INVISIBLE) { 895f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen stopAnimation(); 896f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 897f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen startAnimation(); 898f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 899f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 900f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 901f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 902f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 903f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void invalidateDrawable(Drawable dr) { 904f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (!mInDrawing) { 905f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (verifyDrawable(dr)) { 906f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final Rect dirty = dr.getBounds(); 907f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final int scrollX = mScrollX + mPaddingLeft; 908f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen final int scrollY = mScrollY + mPaddingTop; 909f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 910f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen invalidate(dirty.left + scrollX, dirty.top + scrollY, 911f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen dirty.right + scrollX, dirty.bottom + scrollY); 912f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 913f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.invalidateDrawable(dr); 914f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 915f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 916f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 917f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 918f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 919f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected void onSizeChanged(int w, int h, int oldw, int oldh) { 920f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen updateDrawableBounds(w, h); 921f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 922f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 923f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private void updateDrawableBounds(int w, int h) { 924f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // onDraw will translate the canvas so we draw starting at 0,0 925f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int right = w - mPaddingRight - mPaddingLeft; 926f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int bottom = h - mPaddingBottom - mPaddingTop; 9270962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen int top = 0; 9280962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen int left = 0; 929f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 930f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminateDrawable != null) { 9310962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen // Aspect ratio logic does not apply to AnimationDrawables 9320962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen if (mOnlyIndeterminate && !(mIndeterminateDrawable instanceof AnimationDrawable)) { 9330962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen // Maintain aspect ratio. Certain kinds of animated drawables 9340962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen // get very confused otherwise. 9350962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen final int intrinsicWidth = mIndeterminateDrawable.getIntrinsicWidth(); 9360962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen final int intrinsicHeight = mIndeterminateDrawable.getIntrinsicHeight(); 9370962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen final float intrinsicAspect = (float) intrinsicWidth / intrinsicHeight; 9380962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen final float boundAspect = (float) w / h; 9390962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen if (intrinsicAspect != boundAspect) { 9400962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen if (boundAspect > intrinsicAspect) { 9410962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen // New width is larger. Make it smaller to match height. 9420962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen final int width = (int) (h * intrinsicAspect); 9430962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen left = (w - width) / 2; 9440962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen right = left + width; 9450962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen } else { 9460962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen // New height is larger. Make it smaller to match width. 9470962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen final int height = (int) (w * (1 / intrinsicAspect)); 9480962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen top = (h - height) / 2; 9490962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen bottom = top + height; 9500962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen } 9510962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen } 9520962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen } 9530962a4b159ae5d4ea427c9e6fc32ff3722cbc16cMarco Nelissen mIndeterminateDrawable.setBounds(left, top, right, bottom); 954f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 955f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 956f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mProgressDrawable != null) { 957f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mProgressDrawable.setBounds(0, 0, right, bottom); 958f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 959f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 960f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 961f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 962f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected synchronized void onDraw(Canvas canvas) { 963f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.onDraw(canvas); 964f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 965f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable d = mCurrentDrawable; 966f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (d != null) { 967f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // Translate canvas so a indeterminate circular progress bar with padding 968f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // rotates properly in its animation 969f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen canvas.save(); 970f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen canvas.translate(mPaddingLeft, mPaddingTop); 971f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen long time = getDrawingTime(); 972f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mAnimation != null) { 973f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mAnimation.getTransformation(time, mTransformation); 974f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen float scale = mTransformation.getAlpha(); 975f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen try { 976f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mInDrawing = true; 977f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen d.setLevel((int) (scale * MAX_LEVEL)); 978f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } finally { 979f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mInDrawing = false; 980f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 981f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (SystemClock.uptimeMillis() - mLastDrawTime >= mAnimationResolution) { 982f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mLastDrawTime = SystemClock.uptimeMillis(); 983f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen postInvalidateDelayed(mAnimationResolution); 984f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 985f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 986f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen d.draw(canvas); 987f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen canvas.restore(); 988f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mShouldStartAnimationDrawable && d instanceof Animatable) { 989f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen ((Animatable) d).start(); 990f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mShouldStartAnimationDrawable = false; 991f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 992f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 993f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 994f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 995f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 996f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 997f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable d = mCurrentDrawable; 998f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 999f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int dw = 0; 1000f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int dh = 0; 1001f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (d != null) { 1002f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen dw = Math.max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth())); 1003f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen dh = Math.max(mMinHeight, Math.min(mMaxHeight, d.getIntrinsicHeight())); 1004f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1005f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen updateDrawableState(); 1006f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen dw += mPaddingLeft + mPaddingRight; 1007f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen dh += mPaddingTop + mPaddingBottom; 1008f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1009f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setMeasuredDimension(resolveSizeAndState(dw, widthMeasureSpec, 0), 1010f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen resolveSizeAndState(dh, heightMeasureSpec, 0)); 1011f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1012f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1013f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 1014f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected void drawableStateChanged() { 1015f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.drawableStateChanged(); 1016f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen updateDrawableState(); 1017f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1018f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1019f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private void updateDrawableState() { 1020f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int[] state = getDrawableState(); 1021f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1022f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mProgressDrawable != null && mProgressDrawable.isStateful()) { 1023f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mProgressDrawable.setState(state); 1024f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1025f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1026f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminateDrawable != null && mIndeterminateDrawable.isStateful()) { 1027f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mIndeterminateDrawable.setState(state); 1028f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1029f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1030f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1031f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen static class SavedState extends BaseSavedState { 1032f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int progress; 1033f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int secondaryProgress; 1034f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1035f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 1036f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Constructor called from {@link ProgressBar#onSaveInstanceState()} 1037f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 1038f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen SavedState(Parcelable superState) { 1039f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super(superState); 1040f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1041f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1042f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 1043f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Constructor called from {@link #CREATOR} 1044f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 1045f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private SavedState(Parcel in) { 1046f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super(in); 1047f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen progress = in.readInt(); 1048f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen secondaryProgress = in.readInt(); 1049f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1050f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1051f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 1052f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void writeToParcel(Parcel out, int flags) { 1053f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.writeToParcel(out, flags); 1054f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen out.writeInt(progress); 1055f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen out.writeInt(secondaryProgress); 1056f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1057f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1058f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public static final Parcelable.Creator<SavedState> CREATOR 1059f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen = new Parcelable.Creator<SavedState>() { 1060f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public SavedState createFromParcel(Parcel in) { 1061f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return new SavedState(in); 1062f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1063f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1064f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public SavedState[] newArray(int size) { 1065f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return new SavedState[size]; 1066f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1067f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen }; 1068f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1069f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1070f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 1071f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public Parcelable onSaveInstanceState() { 1072f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // Force our ancestor class to save its state 1073f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Parcelable superState = super.onSaveInstanceState(); 1074f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen SavedState ss = new SavedState(superState); 1075f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1076f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen ss.progress = mProgress; 1077f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen ss.secondaryProgress = mSecondaryProgress; 1078f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1079f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return ss; 1080f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1081f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1082f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 1083f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void onRestoreInstanceState(Parcelable state) { 1084f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen SavedState ss = (SavedState) state; 1085f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.onRestoreInstanceState(ss.getSuperState()); 1086f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1087f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setProgress(ss.progress); 1088f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setSecondaryProgress(ss.secondaryProgress); 1089f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1090f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1091f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 1092f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected void onAttachedToWindow() { 1093f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.onAttachedToWindow(); 1094f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminate) { 1095f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen startAnimation(); 1096f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1097f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1098f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1099f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 1100f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected void onDetachedFromWindow() { 1101f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mIndeterminate) { 1102f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen stopAnimation(); 1103f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1104f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if(mRefreshProgressRunnable != null) { 1105f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen removeCallbacks(mRefreshProgressRunnable); 1106f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1107f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mAccessibilityEventSender != null) { 1108f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen removeCallbacks(mAccessibilityEventSender); 1109f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1110f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // This should come after stopAnimation(), otherwise an invalidate message remains in the 1111f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // queue, which can prevent the entire view hierarchy from being GC'ed during a rotation 1112f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.onDetachedFromWindow(); 1113f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1114f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1115f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 1116f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 1117f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.onInitializeAccessibilityEvent(event); 1118f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen event.setItemCount(mMax); 1119f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen event.setCurrentItemIndex(mProgress); 1120f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1121f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1122f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 1123f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Schedule a command for sending an accessibility event. 1124f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * </br> 1125f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Note: A command is used to ensure that accessibility events 1126f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * are sent at most one in a given time frame to save 1127f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * system resources while the progress changes quickly. 1128f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 1129f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private void scheduleAccessibilityEventSender() { 1130f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mAccessibilityEventSender == null) { 1131f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mAccessibilityEventSender = new AccessibilityEventSender(); 1132f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 1133f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen removeCallbacks(mAccessibilityEventSender); 1134f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1135f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen postDelayed(mAccessibilityEventSender, TIMEOUT_SEND_ACCESSIBILITY_EVENT); 1136f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1137f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 1138f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 1139f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Command for sending an accessibility event. 1140f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 1141f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private class AccessibilityEventSender implements Runnable { 1142f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void run() { 1143f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); 1144f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1145f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 1146f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen} 1147