Home | History | Annotate | Download | only in utils
      1 package com.android.mail.utils;
      2 
      3 import android.os.Handler;
      4 import android.view.View;
      5 import android.view.ViewTreeObserver;
      6 
      7 /**
      8  * Given a View to monitor draws on, an instance of this class will notify a listener of state
      9  * changes between {@link #STATE_ACTIVE} and {@link #STATE_IDLE}.
     10  * <p>
     11  * Any drawing will instantly trigger {@link #STATE_ACTIVE}. {@link #STATE_IDLE} is only
     12  * subsequently triggered if {@link #IDLE_WINDOW_MS} continuous milliseconds elapse with zero draws.
     13  */
     14 public class DrawIdler {
     15 
     16     public static final int STATE_IDLE = 0;
     17     public static final int STATE_ACTIVE = 1;
     18 
     19     private static final int IDLE_WINDOW_MS = 100;
     20 
     21     private int mState = STATE_IDLE;
     22 
     23     private View mRoot;
     24     private IdleListener mListener;
     25     private final IdleReader mIdleReader = new IdleReader();
     26     private final Handler mHandler = new Handler();
     27 
     28     public interface IdleListener {
     29         void onStateChanged(DrawIdler idler, int newState);
     30     }
     31 
     32     public void setListener(IdleListener listener) {
     33         mListener = listener;
     34         if (mListener != null) {
     35             mListener.onStateChanged(this, mState);
     36         }
     37     }
     38 
     39     public void setRootView(View rootView) {
     40         if (mRoot == rootView) {
     41             return;
     42         } else if (mRoot != null) {
     43             mRoot.getViewTreeObserver().removeOnPreDrawListener(mIdleReader);
     44         }
     45 
     46         mRoot = rootView;
     47 
     48         if (mRoot != null) {
     49             mRoot.getViewTreeObserver().addOnPreDrawListener(mIdleReader);
     50         }
     51     }
     52 
     53     public int getCurrentState() {
     54         return mState;
     55     }
     56 
     57     private void setState(int newState) {
     58         if (mState == newState) {
     59             return;
     60         }
     61         mState = newState;
     62         if (mListener != null) {
     63             mListener.onStateChanged(this, newState);
     64         }
     65     }
     66 
     67     // this inner class keeps implementation details private
     68     // (we use OnPreDrawListener instead of OnDrawListener because the latter is only JB+)
     69     private class IdleReader implements Runnable, ViewTreeObserver.OnPreDrawListener {
     70 
     71         @Override
     72         public void run() {
     73             setState(STATE_IDLE);
     74         }
     75 
     76         @Override
     77         public boolean onPreDraw() {
     78             setState(STATE_ACTIVE);
     79             mHandler.removeCallbacks(this);
     80             mHandler.postDelayed(this, IDLE_WINDOW_MS);
     81             return true; // always allow the draw; we're only here to observe
     82         }
     83 
     84     }
     85 
     86 }
     87