1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.gallery3d.util; 18 19 import android.app.Activity; 20 import android.os.Handler; 21 import android.os.Message; 22 import android.os.SystemClock; 23 24 import java.util.WeakHashMap; 25 26 /** 27 * This class manages the visibility of the progress spinner in the action bar for an 28 * Activity. It filters out short-lived appearances of the progress spinner by only 29 * showing the spinner if it hasn't been hidden again before the end of a specified 30 * delay period. It also enforces a minimum display time once the spinner is made visible. 31 * This meant to cut down on the frequent "flashes" of the progress spinner. 32 */ 33 public class SpinnerVisibilitySetter { 34 35 private static final int MSG_SHOW_SPINNER = 1; 36 private static final int MSG_HIDE_SPINNER = 2; 37 38 // Amount of time after a show request that the progress spinner is actually made visible. 39 // This means that any show/hide requests that happen subsequently within this period 40 // of time will be ignored. 41 private static final long SPINNER_DISPLAY_DELAY = 1000; 42 43 // The minimum amount of time the progress spinner must be visible before it can be hidden. 44 private static final long MIN_SPINNER_DISPLAY_TIME = 2000; 45 46 static final WeakHashMap<Activity, SpinnerVisibilitySetter> sInstanceMap = 47 new WeakHashMap<Activity, SpinnerVisibilitySetter>(); 48 49 private long mSpinnerVisibilityStartTime = -1; 50 private Activity mActivity; 51 52 private Handler mHandler = new Handler() { 53 @Override 54 public void handleMessage(Message msg) { 55 switch(msg.what) { 56 case MSG_SHOW_SPINNER: 57 removeMessages(MSG_SHOW_SPINNER); 58 if (mSpinnerVisibilityStartTime >= 0) break; 59 mSpinnerVisibilityStartTime = SystemClock.elapsedRealtime(); 60 mActivity.setProgressBarIndeterminateVisibility(true); 61 break; 62 case MSG_HIDE_SPINNER: 63 removeMessages(MSG_HIDE_SPINNER); 64 if (mSpinnerVisibilityStartTime < 0) break; 65 long t = SystemClock.elapsedRealtime() - mSpinnerVisibilityStartTime; 66 if (t >= MIN_SPINNER_DISPLAY_TIME) { 67 mSpinnerVisibilityStartTime = -1; 68 mActivity.setProgressBarIndeterminateVisibility(false); 69 } else { 70 sendEmptyMessageDelayed(MSG_HIDE_SPINNER, MIN_SPINNER_DISPLAY_TIME - t); 71 } 72 break; 73 } 74 } 75 }; 76 77 /** 78 * Gets the <code>SpinnerVisibilitySetter</code> for the given <code>activity</code>. 79 * 80 * This method must be called from the main thread. 81 */ 82 public static SpinnerVisibilitySetter getInstance(Activity activity) { 83 synchronized(sInstanceMap) { 84 SpinnerVisibilitySetter setter = sInstanceMap.get(activity); 85 if (setter == null) { 86 setter = new SpinnerVisibilitySetter(activity); 87 sInstanceMap.put(activity, setter); 88 } 89 return setter; 90 } 91 } 92 93 private SpinnerVisibilitySetter(Activity activity) { 94 mActivity = activity; 95 } 96 97 public void setSpinnerVisibility(boolean visible) { 98 if (visible) { 99 mHandler.removeMessages(MSG_HIDE_SPINNER); 100 mHandler.sendEmptyMessageDelayed(MSG_SHOW_SPINNER, SPINNER_DISPLAY_DELAY); 101 } else { 102 mHandler.removeMessages(MSG_SHOW_SPINNER); 103 mHandler.sendEmptyMessage(MSG_HIDE_SPINNER); 104 } 105 } 106 } 107