记录下,可拖动的刻度尺
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;
}
}
}
}