可拖动的刻度尺

记录下,可拖动的刻度尺

package com.myf.scrollerscalerulerview;


import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.widget.Scroller;
/**
 * 可拖动的刻度尺
 * @author ZH-SW-Mengyf
 *
 */
public class ScaleRulerSeekBar extends ScaleRulerProgressBar{
	private int mMinVelocity;
	private Scroller mScroller;
	private VelocityTracker mVelocityTracker;
	/** 记录被触摸的坐标 */
	protected int mEventX;
	private int mLastProgress = -1;
	/** 正在滚动中 */
	private boolean isScrolling = false;
	
	private OnSeekBarChangeListener mOnSeekBarChangeListener;
	
	/**
	 * 数据改变监听
	 * @author Mengyf
	 *
	 */
	public interface OnSeekBarChangeListener {
		void onProgressChanged(ScaleRulerSeekBar scrollerRulerSeekBar,long progress,boolean fromUser,boolean isScrolling);
		void onStartTrackingTouch(ScaleRulerSeekBar scrollerRulerSeekBar);
		void onStopTrackingTouch(ScaleRulerSeekBar scrollerRulerSeekBar);
	}
	
	/**
	 * 设置进度监听
	 * @param l
	 */
	public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {
		mOnSeekBarChangeListener = l;
	}
	
	public ScaleRulerSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init(context);
	}

	public ScaleRulerSeekBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public ScaleRulerSeekBar(Context context) {
		super(context);
		init(context);
	}
	
	private void init(Context context) {
		mScroller = new Scroller(getContext());
		mMinVelocity = ViewConfiguration.get(getContext()).getScaledMinimumFlingVelocity();
	}
	/**
	 * 添加用户的速度跟踪器
	 */
	private void addVelocityTracker(MotionEvent event) {
		if (mVelocityTracker == null) {
			mVelocityTracker = VelocityTracker.obtain();
		}
		mVelocityTracker.addMovement(event);
	}
	
	/**
	 * 移除用户速度跟踪器
	 */
	private void recycleVelocityTracker() {
		if (mVelocityTracker != null) {
			mVelocityTracker.recycle();
			mVelocityTracker = null;
		}
	}

	@SuppressLint("Recycle")
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int eventX = (int) event.getX();
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			addVelocityTracker(event);
			setPressed(true);
			//停止缓冲
			 mScroller.forceFinished(true);
			 mEventX = eventX;
			notifyStartTrackingTouch();
			break;

		case MotionEvent.ACTION_MOVE:
			addVelocityTracker(event);
			setPressed(true);
			changeMove(eventX);
			break;

		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:
			setPressed(false);
			changeMove(eventX);
			notifyStopTrackingTouch();
			setProgress(getProgress(), false, true);
			scrollerFling();
			recycleVelocityTracker();
			 mEventX = 0;
			return false;
		default:
			break;
		}

		mEventX = eventX;
		return true;
	}
	
	/**
	 * 移动数据中
	 * @param eventX
	 */
	private void changeMove(int eventX) {
		mOffsetX -= (mEventX - eventX);
		
		
		if (isInvalidOffset(mOffsetX)) {
			setScrolling(false);
			//停止缓冲
			mScroller.forceFinished(true);
		}
		int tempProgress = offsetXToProgress(getValidOffset(mOffsetX));
		
		setProgress(tempProgress, false, false);
		
		notifyProgressChanged(getProgress(),false);
		
		postInvalidate();
	}
	
	/**
	 * 滚动缓冲
	 */
	protected void scrollerFling() {
		float xVelocity = 0;
		if (mVelocityTracker != null) {
			mVelocityTracker.computeCurrentVelocity(1000);
			xVelocity = mVelocityTracker.getXVelocity();
		}
		if (Math.abs(xVelocity) > mMinVelocity) {
			if (mScroller != null) {
				mScroller.fling(0, 0, (int) xVelocity, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0);
			}
		}
	}
	
	/**
	 * 通知进进度开始按下
	 * @param progress
	 */
	private void notifyStartTrackingTouch() {
		if (mOnSeekBarChangeListener != null) {
			mOnSeekBarChangeListener.onStartTrackingTouch(this);
		}
	}
	
	/**
	 * 
	 * 通知进度改变
	 * @param progress进度
	 * @param isChange 强制改变,进行回调
	 */
	private void notifyProgressChanged(int progress,boolean isChange) {
		if (mLastProgress != progress || isChange) {
			mLastProgress = progress;
			if (mOnSeekBarChangeListener != null) {
				mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), isPressed(), isScrolling());
			}
		}
	}
	
	/**
	 * 抬手通知
	 */
	private void notifyStopTrackingTouch() {
		if (mOnSeekBarChangeListener != null) {
			mOnSeekBarChangeListener.onStopTrackingTouch(this);
		}
	}
	
	/**
	 * 将坐标转换为进度值
	 * 
	 * @param offsetX
	 * @return
	 */
	protected int offsetXToProgress(float offsetX) {
		float offset = (Math.abs(offsetX) - getRulerWidth() / 2) / getRulerDistance();
		int progress = Math.round(offset);
		return progress;
	}
	
	/**
	 * 滚动中
	 * @return
	 */
	public boolean isScrolling() {
		return isScrolling;
	}
	
	/**
	 * 设置当前滚动状态
	 * @param isScrolling
	 */
	private void setScrolling(boolean isScrolling) {
		this.isScrolling = isScrolling;
	}
	
	@Override
	public void computeScroll() {
		super.computeScroll();
		Log.d("myf", "---------computeScroll--------------");
		if (mScroller.computeScrollOffset()) {
			if (mScroller.getCurrX() == mScroller.getFinalX()) { // over
				setScrolling(false);
				setProgress(getProgress(), false, true);
				notifyProgressChanged(getProgress(),true);
			} 
			else {
				setScrolling(true);
				int xPosition = mScroller.getCurrX();
				changeMove(xPosition);
				mEventX = xPosition;
			}
		}
	}
	
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值