/*
* Code taken from jasta's five project:
* http://code.google.com/p/five/
*
* Much of this logic was taken from Romain Guy's Shelves project:
*
* http://code.google.com/p/shelves/
*/
package com.todayinfo.ui.component.fastscroll;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
/**
* Abstracts a mechanism for determining an appropriate time to load images into
* an animating ListView. That is, only load the images when the list view is
* not flinging.
*
* To use, you must make sure that you call through to
* {@link onScrollStateChanged} and {@link onTouch}.
*
* This class was inspired by Romain Guy's ShelvesActivity. Rather, it was
* blatantly lifted from it :)
*/
public class IdleListDetector {
private final ScrollHandler mScrollHandler;
private final OnListIdleListener mListener;
/*
* Time to wait before loading the images while the user still has their
* finger grabbing the list but is not currently flinging.
*/
private static final int DELAY_IDLE_DETECTION = 550;
private static final int DELAY_FAST_IDLE_DETECTION = DELAY_IDLE_DETECTION;
private static final String TAG = "IdleListDetector";
private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
/* Special considerations for FastScrollView. */
private int mFastScrollState = FastScrollView.SCROLL_STATE_FAST_IDLE;
private boolean mFingerUp = true;
private boolean mPending = false;
public IdleListDetector(OnListIdleListener l) {
mListener = l;
mScrollHandler = new ScrollHandler();
}
public boolean isListIdle() {
if (mScrollState == OnScrollListener.SCROLL_STATE_FLING)
return false;
if (mPending == true)
return false;
return true;
}
public interface OnListIdleListener {
void onListIdle();
}
public boolean onTouch(View v, MotionEvent ev) {
int action = ev.getAction();
mFingerUp = (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL);
if (mFingerUp && mScrollState != OnScrollListener.SCROLL_STATE_FLING) {
Log.i(TAG, "4");
mScrollHandler.sendListIdle(true);
}
return false;
}
public void onFastScrollStateChanged(AbsListView view, int scrollState) {
if (mFastScrollState == FastScrollView.SCROLL_STATE_FAST_SCROLLING
&& scrollState != FastScrollView.SCROLL_STATE_FAST_SCROLLING) {
Log.i(TAG, "1");
mScrollHandler.sendListIdle(true);
}
else if (scrollState == FastScrollView.SCROLL_STATE_FAST_SCROLLING) {
Log.i(TAG, "2");
mScrollHandler.sendListIdle(DELAY_FAST_IDLE_DETECTION);
}
if (scrollState == FastScrollView.SCROLL_STATE_FAST_IDLE)
mFingerUp = true;
mFastScrollState = scrollState;
mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
}
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (mScrollState == OnScrollListener.SCROLL_STATE_FLING
&& scrollState != OnScrollListener.SCROLL_STATE_FLING) {
Log.i(TAG, "3");
mScrollHandler.sendListIdle(mFingerUp);
} else if (scrollState == OnScrollListener.SCROLL_STATE_FLING)
mScrollHandler.cancelListIdle();
mScrollState = scrollState;
}
private class ScrollHandler extends Handler {
private static final int MSG_LIST_IDLE = 0;
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_LIST_IDLE:
mPending = false;
mListener.onListIdle();
break;
}
}
public void sendListIdle(int delay) {
Message m = obtainMessage(MSG_LIST_IDLE);
removeMessages(MSG_LIST_IDLE);
mPending = true;
sendMessageDelayed(m, delay);
}
public void sendListIdle(boolean fingerUp) {
sendListIdle(fingerUp ? 0 : DELAY_IDLE_DETECTION);
}
public void cancelListIdle() {
mPending = false;
removeMessages(MSG_LIST_IDLE);
}
}
}