欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android HorizontalScrollView实现滚动监听

程序员文章站 2024-01-16 21:37:04
...

网上大部分都是直接调用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进去,不然会出错。