ContentLoadingProgressBar.java revision befff92741b1f0629d9a9389a3889cca56d914a2
1befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini/* 2befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * Copyright (C) 2013 The Android Open Source Project 3befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * 4befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * Licensed under the Apache License, Version 2.0 (the "License"); 5befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * you may not use this file except in compliance with the License. 6befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * You may obtain a copy of the License at 7befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * 8befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * http://www.apache.org/licenses/LICENSE-2.0 9befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * 10befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * Unless required by applicable law or agreed to in writing, software 11befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * distributed under the License is distributed on an "AS IS" BASIS, 12befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * See the License for the specific language governing permissions and 14befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * limitations under the License. 15befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini */ 16befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 17befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpinipackage android.support.v4.widget; 18befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 19befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpiniimport android.content.Context; 20befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpiniimport android.util.AttributeSet; 21befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpiniimport android.view.View; 22befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpiniimport android.widget.ProgressBar; 23befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 24befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini/** 25befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * ContentLoadingProgressBar implements a ProgressBar that waits a minimum time to be 26befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * dismissed before showing. Once visible, the progress bar will be visible for 27befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * a minimum amount of time to avoid "flashes" in the UI when an event could take 28befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * a largely variable time to complete (from none, to a user perceivable amount) 29befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini */ 30befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpinipublic class ContentLoadingProgressBar extends ProgressBar { 31befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini private static final int MIN_SHOW_TIME = 500; // ms 32befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini private static final int MIN_DELAY = 500; // ms 33befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 34befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini private long mStartTime = -1; 35befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 36befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini private boolean mPostedHide = false; 37befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 38befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini private boolean mPostedShow = false; 39befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 40befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini private boolean mDismissed = false; 41befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 42befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini private final Runnable mDelayedHide = new Runnable() { 43befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 44befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini @Override 45befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini public void run() { 46befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini mPostedHide = false; 47befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini mStartTime = -1; 48befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini setVisibility(View.GONE); 49befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 50befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini }; 51befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 52befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini private final Runnable mDelayedShow = new Runnable() { 53befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 54befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini @Override 55befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini public void run() { 56befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini mPostedShow = false; 57befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini if (!mDismissed) { 58befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini mStartTime = System.currentTimeMillis(); 59befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini setVisibility(View.VISIBLE); 60befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 61befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 62befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini }; 63befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 64befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini public ContentLoadingProgressBar(Context context) { 65befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini this(context, null); 66befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 67befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 68befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini public ContentLoadingProgressBar(Context context, AttributeSet attrs) { 69befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini super(context, attrs, 0); 70befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 71befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 72befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini @Override 73befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini public void onAttachedToWindow() { 74befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini super.onAttachedToWindow(); 75befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini removeCallbacks(); 76befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 77befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 78befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini @Override 79befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini public void onDetachedFromWindow() { 80befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini super.onDetachedFromWindow(); 81befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini removeCallbacks(); 82befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 83befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 84befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini private void removeCallbacks() { 85befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini removeCallbacks(mDelayedHide); 86befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini removeCallbacks(mDelayedShow); 87befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 88befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 89befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini /** 90befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * Hide the progress view if it is visible. The progress view will not be 91befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * hidden until it has been shown for at least a minimum show time. If the 92befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * progress view was not yet visible, cancels showing the progress view. 93befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini */ 94befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini public void hide() { 95befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini mDismissed = true; 96befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini removeCallbacks(mDelayedShow); 97befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini long diff = System.currentTimeMillis() - mStartTime; 98befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini if (diff >= MIN_SHOW_TIME || mStartTime == -1) { 99befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini // The progress spinner has been shown long enough 100befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini // OR was not shown yet. If it wasn't shown yet, 101befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini // it will just never be shown. 102befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini setVisibility(View.GONE); 103befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } else { 104befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini // The progress spinner is shown, but not long enough, 105befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini // so put a delayed message in to hide it when its been 106befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini // shown long enough. 107befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini if (!mPostedHide) { 108befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini postDelayed(mDelayedHide, MIN_SHOW_TIME - diff); 109befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini mPostedHide = true; 110befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 111befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 112befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 113befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini 114befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini /** 115befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * Show the progress view after waiting for a minimum delay. If 116befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini * during that time, hide() is called, the view is never made visible. 117befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini */ 118befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini public void show() { 119befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini // Reset the start time. 120befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini mStartTime = -1; 121befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini mDismissed = false; 122befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini removeCallbacks(mDelayedHide); 123befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini if (!mPostedShow) { 124befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini postDelayed(mDelayedShow, MIN_DELAY); 125befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini mPostedShow = true; 126befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 127befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini } 128befff92741b1f0629d9a9389a3889cca56d914a2Mindy DelliCarpini} 129