package com.nostra13.universalimageloader.core.assist; import java.util.concurrent.atomic.AtomicInteger; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.GridView; import android.widget.ListView; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; /** * Listener-helper for {@linkplain AbsListView list views} ({@link ListView}, {@link GridView}) which makes some * {@link #LOADING_DELAY_ON_FLING delay} before starting image loading during touch scrolling and/or fast list scrolling * (fling). It prevents redundant loadings.<br /> * Set it to your list view's {@link AbsListView#setOnScrollListener(OnScrollListener) setOnScrollListener(...)} and * later get options (using {@linkplain #getOptions()}) for * {@link ImageLoader#displayImage(String, android.widget.ImageView, DisplayImageOptions) ImageLoader.displayImage(...)} * calls. * * @author Sergey Tarasevich (nostra13[at]gmail[dot]com) */ public class OnScrollSmartOptions implements OnScrollListener { /** {@value} */ public static final int LOADING_DELAY_ON_TOUCH_SCROLL = 0; // ms /** {@value} */ public static final int LOADING_DELAY_ON_FLING = 300; // ms private final DisplayImageOptions options; private final DisplayImageOptions scrollOptions; private final DisplayImageOptions flingOptions; private final OnScrollListener externalListener; private final AtomicInteger scrollState; /** * Constructor<br /> * Delay before loading for touch scrolling - {@value #LOADING_DELAY_ON_TOUCH_SCROLL} ms<br /> * Delay before loading for fling scrolling - {@value #LOADING_DELAY_ON_FLING} ms * * @param displayOptions * {@linkplain DisplayImageOptions Display options} you want to use for displaying images in you * {@linkplain AbsListView list view} */ public OnScrollSmartOptions(DisplayImageOptions displayOptions) { this(displayOptions, LOADING_DELAY_ON_TOUCH_SCROLL, LOADING_DELAY_ON_FLING); } /** * Constructor * * @param displayOptions * {@linkplain DisplayImageOptions Display options} you want to use for displaying images in you * {@linkplain AbsListView list view} * @param loadingDelayOnScroll * Delay (in milliseconds) before starting loading during scrolling * @param loadingDelayOnFling * Delay (in milliseconds) before starting loading during fast scrolling (fling) */ public OnScrollSmartOptions(DisplayImageOptions displayOptions, int loadingDelayOnScroll, int loadingDelayOnFling) { this(displayOptions, loadingDelayOnScroll, loadingDelayOnFling, null); } /** * Constructor * * @param displayOptions * {@linkplain DisplayImageOptions Display options} you want to use for displaying images in you * {@linkplain AbsListView list view} * @param loadingDelayOnScroll * Delay (in milliseconds) before starting loading during touch scrolling * @param loadingDelayOnFling * Delay (in milliseconds) before starting loading during fast scrolling (fling) * @param customListener * Your custom {@link OnScrollListener} for {@linkplain AbsListView list view} which also will be get * scroll events */ public OnScrollSmartOptions(DisplayImageOptions displayOptions, int loadingDelayOnScroll, int loadingDelayOnFling, OnScrollListener customListener) { options = displayOptions; scrollOptions = new DisplayImageOptions.Builder() .cloneFrom(options) .delayBeforeLoading(loadingDelayOnScroll) .build(); flingOptions = new DisplayImageOptions.Builder() .cloneFrom(options) .delayBeforeLoading(loadingDelayOnFling) .build(); externalListener = customListener; scrollState = new AtomicInteger(OnScrollListener.SCROLL_STATE_IDLE); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { this.scrollState.set(scrollState); if (externalListener != null) { externalListener.onScrollStateChanged(view, scrollState); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (externalListener != null) { externalListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); } } /** * Returns appropriate {@linkplain DisplayImageOptions display options} depending on {@linkplain AbsListView list * view's} current scrolling state */ public DisplayImageOptions getOptions() { switch (scrollState.get()) { case OnScrollListener.SCROLL_STATE_IDLE: return options; case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: return scrollOptions; case OnScrollListener.SCROLL_STATE_FLING: return flingOptions; default: return options; } } }