Home | History | Annotate | Download | only in util
      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