android HorizontalScrollView实现滚动监听

网上大部分都是直接调用onScrollChanged(int x, int y, int oldx, int oldy) 这个方法的,实际上只是将这个方法的protected改为public而已,本质上上还是没有什么多大的帮助,不多少,直接上代码

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;

public class ScrollListenerHorizontalScrollView extends HorizontalScrollView{

	public ScrollListenerHorizontalScrollView(Context context,
			AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}

	public ScrollListenerHorizontalScrollView(Context context,
			AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public ScrollListenerHorizontalScrollView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}
	
	
	public interface ScrollViewListener {  
		  
	    void onScrollChanged(ScrollType scrollType);  
	  
	}  
	
	private Handler mHandler;
	private ScrollViewListener scrollViewListener;
	/**
	 * 滚动状态   IDLE 滚动停止  TOUCH_SCROLL 手指拖动滚动         FLING滚动
	 * @version XHorizontalScrollViewgallery	
	 * @author DZC
	 * @Time  2014-12-7 上午11:06:52
	 *
	 *
	 */
    enum ScrollType{IDLE,TOUCH_SCROLL,FLING};
    
    /**
     * 记录当前滚动的距离
     */
    private int currentX = -9999999;
    /**
     * 当前滚动状态
     */
    private ScrollType scrollType = ScrollType.IDLE;
    /**
     * 滚动监听间隔
     */
    private int scrollDealy = 50;
    /**
     * 滚动监听runnable
     */
    private Runnable scrollRunnable = new Runnable() {
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			if(getScrollX()==currentX){
				//滚动停止  取消监听线程
				Log.d("", "停止滚动");
				scrollType = ScrollType.IDLE;
				if(scrollViewListener!=null){
					scrollViewListener.onScrollChanged(scrollType);
				}
				mHandler.removeCallbacks(this);
				return;
			}else{
				//手指离开屏幕    view还在滚动的时候
				Log.d("", "Fling。。。。。");
				scrollType = ScrollType.FLING;
				if(scrollViewListener!=null){
					scrollViewListener.onScrollChanged(scrollType);
				}
			}
			currentX = getScrollX();
			mHandler.postDelayed(this, scrollDealy);
		}
	};


	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
		case MotionEvent.ACTION_MOVE:
			this.scrollType = ScrollType.TOUCH_SCROLL;
			scrollViewListener.onScrollChanged(scrollType);
			//手指在上面移动的时候   取消滚动监听线程
			mHandler.removeCallbacks(scrollRunnable);
			break;
		case MotionEvent.ACTION_UP:
			//手指移动的时候
			mHandler.post(scrollRunnable);
			break;
		}
		return super.onTouchEvent(ev);
	}

	/**
	 * 必须先调用这个方法设置Handler  不然会出错
	 *  2014-12-7 下午3:55:39 
	 * @author DZC
	 * @return void
	 * @param handler  	
	 * @TODO
	 */
	public void setHandler(Handler handler){
		this.mHandler = handler;
	}
	/**
	 * 设置滚动监听
	 *  2014-12-7 下午3:59:51 
	 * @author DZC
	 * @return void
	 * @param listener  	
	 * @TODO
	 */
	public void setOnScrollStateChangedListener(ScrollViewListener listener){
		this.scrollViewListener = listener;
	}

}

代码注释已经写得我认为很详细了,不懂的可以留言,说下思路,就是开启一个线程,每个一定的时间间隔去判断当前的scrollX是否有改变,要是有改变就说明还在滚动,要是没有改变就说明已经停止滚动了。

要注意的一点就是使用的时候必须调用setHandler(Handler handler)传一个在activity创建的Handler进去,不然会出错。

相关推荐