Android自定义一个属于自己的刻度尺
Posted 大白龙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android自定义一个属于自己的刻度尺相关的知识,希望对你有一定的参考价值。
概述
本文只要说的是自定义一个刻度尺,正好学习下android自定义控件,之前写过一篇《Android自定义一个属于自己的时间钟表》,大家如果感兴趣可以去看下,好了不扯淡了,直接上效果:看到这个效果以后估计好多新手会觉得不知道如何入手,但是要是大神看到了就会想用什么方式实现才是最好的。这就是差距啊,没办法像我这个菜鸟只好参考下其他实现方法,写了这个demo,让我们一起来看看实现思路。 我们来分步骤一步一步来实现: 1、绘制刻度尺及刻度值(高,中,低刻度)。 2、绘制底部线。 3、绘制中间箭头。 4、监听手势处理(处理范围越界,及选中)。
第一步:1、自定义View的属性,首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。
<declare-styleable name="RulerView">
<!--最大刻度的颜色-->
<attr name="mMaxScaleColor" format="color"/>
<!--中间刻度的颜色-->
<attr name="mMidScaleColor" format="color"/>
<!--最小刻度的颜色-->
<attr name="mMinScaleColor" format="color"/>
<!--底线的颜色-->
<attr name="mBottomLineColor" format="color"/>
<!--最大刻度的宽度-->
<attr name="mMaxScaleWidth" format="dimension"/>
<!--中间刻度的宽度-->
<attr name="mMidScaleWidth" format="dimension"/>
<!--最小刻度的宽度-->
<attr name="mMinScaleWidth" format="dimension"/>
<!--底线的宽度-->
<attr name="mBottomLineWidth" format="dimension"/>
<!--最大刻度的高度占控件的高度比例-->
<attr name="mMaxScaleHeightRatio" format="float"/>
<!--中间刻度的高度占控件的高度比例-->
<attr name="mMidScaleHeightRatio" format="float"/>
<!--最小刻度的高度占控件的高度比例-->
<attr name="mMinScaleHeightRatio" format="float"/>
<!--是否显示刻度值-->
<attr name="isShowScaleValue" format="boolean"/>
<!--是否刻度渐变 包括刻度值和刻度线及下面的线-->
<attr name="isScaleGradient" format="boolean"/>
<!--刻度值颜色-->
<attr name="mScaleValueColor" format="color"/>
<!--刻度值文字大小-->
<attr name="mScaleValueSize" format="dimension"/>
<!--刻度值间隔-->
<attr name="mScaleSpace" format="dimension"/>
<!-- 当前值-->
<attr name="mCurrentValue" format="integer"/>
<!--最大值-->
<attr name="mMaxValue" format="integer"/>
<!--最小值-->
<attr name="mMinValue" format="integer"/>
<!--刻度基数-->
<attr name="mScaleBase" format="integer"/>
<!--中间图标-->
<attr name="mMiddleImg" format="reference"/>
</declare-styleable>
通过这个attrs大家也看到,我们设置了还是蛮细的,所有的刻度及刻度值颜色大小都设定了,让控件设置更加的灵活。
2、下面创建一个class类为rulerview.class ,并设置main.xml中:
<com.dalong.rulerview.RulerView
android:id="@+id/ruler2"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:mMaxValue="5000"
app:mMinValue="1000"
app:mScaleBase="100"
app:mScaleSpace="10dp"
app:mMaxScaleColor="@color/colorAccent"
app:mMidScaleColor="@color/colorPrimary"
app:mMinScaleColor="@color/colorPrimary"
app:mBottomLineColor="@color/colorAccent"
app:mMaxScaleHeightRatio="0.5"
app:mMidScaleHeightRatio="0.3"
app:mMinScaleHeightRatio="0.2"
app:mMaxScaleWidth="2.5dp"
app:mMidScaleWidth="2dp"
app:mMinScaleWidth="2dp"
app:mBottomLineWidth="2.5dp"
app:mCurrentValue="1000"
app:mScaleValueColor="@color/colorAccent"
app:mScaleValueSize="12sp"
app:mMiddleImg="@mipmap/icon_arrow"
app:isScaleGradient="false"
/>
3、在自定义View的构造方法中,获得我们的自定义的样式
// 默认刻度模式
public static final int MOD_TYPE_SCALE = 5;
//刻度基数 每个刻度代表多少 默认为1
public int mScaleBase=1;
//最大刻度的颜色
public int mMaxScaleColor;
//中间刻度的颜色
public int mMidScaleColor;
//最小刻度的颜色
public int mMinScaleColor;
//底部线的颜色
public int mBottomLineColor;
//最大刻度的宽度
public float mMaxScaleWidth;
//中间刻度的宽度
public float mMidScaleWidth;
//最小刻度的宽度
public float mMinScaleWidth;
//底线的宽度
public float mBottomLineWidth;
//最大刻度的高度占控件的高度比例
public float mMaxScaleHeightRatio;
//中间刻度的高度占控件的高度比例
public float mMidScaleHeightRatio;
//最小刻度的高度占控件的高度比例
public float mMinScaleHeightRatio;
//是否显示刻度值
public boolean isShowScaleValue;
//是否刻度渐变
public boolean isScaleGradient;
//刻度值颜色
public int mScaleValueColor;
//刻度值文字大小
public float mScaleValueSize;
//当前值
public int mCurrentValue;
//最大值
public int mMaxValue;
//最小值
public int mMinValue;
//中间图片
private Bitmap mMiddleImg;
//刻度线画笔
private Paint mScalePaint;
// 刻度值画笔
private TextPaint mScaleValuePaint;
//中间图片画笔
private Paint mMiddleImgPaint;
private float mTpDesiredWidth;
//最大刻度高度
private int mMaxScaleHeight;
//中间刻度高度
private int mMidScaleHeight;
//最小刻度高度
private int mMinScaleHeight;
// 滚动偏移量
private int scrollingOffset;
//间隔S
private int mScaleSpace=20;
// 滚动器
private RulerViewScroller scroller;
// 是否执行滚动
private boolean isScrollingPerformed;
public RulerView(Context context)
this(context,null);
public RulerView(Context context, AttributeSet attrs)
this(context, attrs,0);
public RulerView(Context context, AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.RulerView);
mMaxScaleColor=typedArray.getColor(R.styleable.RulerView_mMaxScaleColor, Color.BLACK);
mMidScaleColor=typedArray.getColor(R.styleable.RulerView_mMidScaleColor, Color.BLACK);
mMinScaleColor=typedArray.getColor(R.styleable.RulerView_mMinScaleColor, Color.BLACK);
mMaxScaleColor=typedArray.getColor(R.styleable.RulerView_mMaxScaleColor, Color.BLACK);
mScaleValueColor=typedArray.getColor(R.styleable.RulerView_mScaleValueColor, Color.BLACK);
mBottomLineColor=typedArray.getColor(R.styleable.RulerView_mBottomLineColor, Color.BLACK);
mMaxScaleWidth = typedArray.getDimensionPixelSize(R.styleable.RulerView_mMaxScaleWidth, 15);
mMidScaleWidth = typedArray.getDimensionPixelSize(R.styleable.RulerView_mMidScaleWidth, 12);
mMinScaleWidth = typedArray.getDimensionPixelSize(R.styleable.RulerView_mMinScaleWidth, 10);
mBottomLineWidth = typedArray.getDimensionPixelSize(R.styleable.RulerView_mBottomLineWidth, 15);
mScaleValueSize = typedArray.getDimensionPixelSize(R.styleable.RulerView_mScaleValueSize, 12);
mScaleSpace = typedArray.getDimensionPixelSize(R.styleable.RulerView_mScaleSpace, 20);
mMaxScaleHeightRatio = typedArray.getFloat(R.styleable.RulerView_mMaxScaleHeightRatio, 0.3f);
mMidScaleHeightRatio = typedArray.getFloat(R.styleable.RulerView_mMidScaleHeightRatio, 0.2f);
mMinScaleHeightRatio = typedArray.getFloat(R.styleable.RulerView_mMinScaleHeightRatio, 0.1f);
isShowScaleValue = typedArray.getBoolean(R.styleable.RulerView_isShowScaleValue, true);
isScaleGradient = typedArray.getBoolean(R.styleable.RulerView_isScaleGradient, true);
mMaxValue = typedArray.getInteger(R.styleable.RulerView_mMaxValue, 100);
mMinValue = typedArray.getInteger(R.styleable.RulerView_mMinValue, 0);
mScaleBase = typedArray.getInteger(R.styleable.RulerView_mScaleBase, 1);
mCurrentValue = typedArray.getInteger(R.styleable.RulerView_mCurrentValue, 0);
setCurrentValue(mCurrentValue);
mMiddleImg = BitmapFactory.decodeResource(getResources(),
typedArray.getResourceId(R.styleable.RulerView_mMiddleImg,R.drawable.ruler_mid_arraw));
typedArray.recycle();
mScalePaint=new Paint(Paint.ANTI_ALIAS_FLAG);
mScalePaint.setStyle(Paint.Style.STROKE);
mScalePaint.setAntiAlias(true);
mScaleValuePaint=new TextPaint(Paint.ANTI_ALIAS_FLAG);
mScaleValuePaint.setColor(mScaleValueColor);
mScaleValuePaint.setTextSize(mScaleValueSize);
mScaleValuePaint.setTextAlign(Paint.Align.CENTER);
mTpDesiredWidth = Layout.getDesiredWidth("0", mScaleValuePaint);
mMiddleImgPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
mMiddleImgPaint.setStyle(Paint.Style.STROKE);
mMiddleImgPaint.setAntiAlias(true);
scroller=new RulerViewScroller(context,scrollingListener);
4、我们重写onMesure:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
setMeasuredDimension(measureWidthSize(widthMeasureSpec),measureHeightSize(heightMeasureSpec));
private int measureHeightSize(int heightMeasureSpec)
int result;
int mode=MeasureSpec.getMode(heightMeasureSpec);
int size=MeasureSpec.getSize(heightMeasureSpec);
if(mode==MeasureSpec.EXACTLY)
result=size;
else
result=(int) (mMiddleImg.getHeight() + getPaddingTop() + getPaddingBottom() + 2 * mScaleValuePaint.getTextSize());
if(mode==MeasureSpec.AT_MOST)
result=Math.min(result,size);
return result;
private int measureWidthSize(int widthMeasureSpec)
int result;
int mode=MeasureSpec.getMode(widthMeasureSpec);
int size=MeasureSpec.getSize(widthMeasureSpec);
if(mode==MeasureSpec.EXACTLY)
result=size;
else
result=400;
if(mode==MeasureSpec.AT_MOST)
result=Math.min(result,size);
return result;
5、设置下三种刻度尺的高度
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
super.onSizeChanged(w, h, oldw, oldh);
if (w == 0 || h == 0)
return;
/**
* 在这里根据控件高度设置三中刻度线的高度
*/
int mHeight = h - getPaddingTop() - getPaddingBottom();
mMaxScaleHeight = (int) (mHeight*mMaxScaleHeightRatio);
mMidScaleHeight = (int) (mHeight*mMidScaleHeightRatio);
mMinScaleHeight = (int) (mHeight*mMinScaleHeightRatio);
6、绘制刻度尺
/**
* 绘制刻度线
* @param canvas
* @param mDrawWidth
* @param mDrawHeight
*/
private void drawScaleLine(Canvas canvas, int mDrawWidth, int mDrawHeight)
int scaleNum= (int) (Math.ceil(mDrawWidth/2f/mScaleSpace))+2;
int distanceX = scrollingOffset;
int currValue = mCurrentValue;
drawScaleLine(canvas,scaleNum,distanceX,currValue,mDrawWidth,mDrawHeight);
/**
* 绘制刻度线
* @param canvas
* @param scaleNum
* @param distanceX
* @param currValue
* @param mDrawWidth
* @param mDrawHeight
*/
private void drawScaleLine(Canvas canvas, int scaleNum, int distanceX, int currValue, int mDrawWidth, int mDrawHeight)
int dy = (int) (mDrawHeight - mTpDesiredWidth - mScaleValuePaint.getTextSize()) - getPaddingBottom();
int value;
float xPosition;
for (int i=0;i<scaleNum;i++)
// 右面
xPosition=mDrawWidth/2f+i*mScaleSpace+distanceX;
value=currValue+i;
if(xPosition<=mDrawWidth && value>=(mMinValue/mScaleBase)&&value<=(mMaxValue/mScaleBase))
drawScaleLine(canvas, value, xPosition, dy, scaleNum, i, mDrawHeight);
//绘制右面线
if(value<(mMaxValue/mScaleBase)&&value>=(mMinValue/mScaleBase))
drawBottomLine(canvas,getAlpha(scaleNum, i),xPosition-mMaxScaleWidth/2, dy, xPosition+mScaleSpace+mMaxScaleWidth/2, dy);
//左面
xPosition=mDrawWidth/2f-i*mScaleSpace+distanceX;
value=currValue-i;
if(xPosition>getPaddingLeft() && value>=(mMinValue/mScaleBase)&&value<=(mMaxValue/mScaleBase))
drawScaleLine( canvas, value, xPosition, dy, scaleNum, i, mDrawHeight);
//绘制左面线
if(value>=(mMinValue/mScaleBase) && value<(mMaxValue/mScaleBase))
drawBottomLine(canvas,getAlpha(scaleNum, i),xPosition-mMaxScaleWidth/2, dy, xPosition+mScaleSpace+mMaxScaleWidth/2, dy);
/**
* 绘制底部线
* @param canvas
* @param alpha
* @param sx
* @param sy
* @param ex
* @param ey
*/
private void drawBottomLine(Canvas canvas,int alpha,float sx,float sy,float ex,float ey)
mScalePaint.setColor(mBottomLineColor);
mScalePaint.setStrokeWidth(mBottomLineWidth);
mScalePaint.setAlpha(alpha);
canvas.drawLine(sx, sy, ex, ey, mScalePaint);
/**
* 绘制刻度尺 左 右
* @param canvas
* @param value
* @param xPosition
* @param dy
* @param scaleNum
* @param i
* @param mDrawHeight
*/
public void drawScaleLine(Canvas canvas,int value, float xPosition,int dy,int scaleNum,int i,int mDrawHeight)
if (value % MOD_TYPE_SCALE == 0)
if(value % (MOD_TYPE_SCALE*2)==0)//大刻度
drawScaleLine(canvas,mMaxScaleWidth,mMaxScaleColor,getAlpha(scaleNum, i),
xPosition,dy,xPosition,dy - mMaxScaleHeight);
if (isShowScaleValue)
mScaleValuePaint.setAlpha(getAlpha(scaleNum, i));
canvas.drawText(String.valueOf(value*mScaleBase), xPosition, mDrawHeight - mTpDesiredWidth, mScaleValuePaint);
else//中刻度
drawScaleLine(canvas,mMidScaleWidth,mMidScaleColor,getAlpha(scaleNum, i),
xPosition,dy,xPosition,dy-mMidScaleHeight);
else// 小刻度
drawScaleLine(canvas,mMinScaleWidth,mMinScaleColor,getAlpha(scaleNum, i),
xPosition,dy,xPosition,dy-mMinScaleHeight);
/**
* 绘制刻度尺刻度
* @param canvas
* @param strokeWidth
* @param scaleColor
* @param alpha
* @param sx
* @param sy
* @param ex
* @param ey
*/
private void drawScaleLine(Canvas canvas,float strokeWidth,int scaleColor,int alpha,float sx,float sy,float ex,float ey)
mScalePaint.setStrokeWidth(strokeWidth);
mScalePaint.setColor(scaleColor);
mScalePaint.setAlpha(alpha);
canvas.drawLine(sx, sy, ex, ey, mScalePaint);
其实上面就是绘制刻度尺的核心办法,主要实现思想就是以中心为开始点向左右绘制刻度线。其中也有一些细节需要大家慢慢去思索的,比如这里包含高,中 ,低的三种刻度线,他们在绘制的时候高度,颜色,宽度都是不一样的设置。怎么区分,我这里也写的比较的清楚。这里我就不在提了。 7、绘制中间箭头图片
/**
* 绘制中间图片
* @param canvas
* @param mDrawWidth
* @param mDrawHeight
*/
private void drawMiddleImg(Canvas canvas, int mDrawWidth, int mDrawHeight)
int left = (mDrawWidth - mMiddleImg.getWidth()) / 2;
int top = (int) (mScaleValuePaint.getTextSize() / 2);
canvas.drawBitmap(mMiddleImg, left, top, mMiddleImgPaint);
以上写完就已经可以实现刻度尺了,但是刻度尺是无法拖动的,效果如下:
下面主要就是需要如何实现拖动的效果,其实这个才是最难的。
这里单独创建一个滑动控制类:
public class RulerViewScroller
//滚动的时间
public static final int SCROLLING_DURATION = 400;
//用于滚动的最小增量
public static final int MIN_DELTA_FOR_SCROLLING = 1;
//Listener
private ScrollingListener listener;
//上下文
private Context context;
// Scrolling
private GestureDetector gestureDetector;
private Scroller scroller;
private int lastScrollX;
private float lastTouchedX;
private boolean isScrollingPerformed;
private final int MESSAGE_SCROLL = 0;
private final int MESSAGE_JUSTIFY = 1;
public RulerViewScroller(Context context, ScrollingListener listener)
this.listener = listener;
this.context = context;
gestureDetector = new GestureDetector(context, gestureListener);
gestureDetector.setIsLongpressEnabled(false);
scroller = new Scroller(context);
scroller.setFriction(0.05f);
/**
* 手势监听
*/
private GestureDetector.SimpleOnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener()
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
return true;
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
lastScrollX = 0;
scroller.fling(0, lastScrollX, (int) -velocityX, 0, -0x7FFFFFFF, 0x7FFFFFFF, 0, 0);
setNextMessage(MESSAGE_SCROLL);
return true;
;
/**
* 手势处理
* @param event
* @return
*/
public boolean onTouchEvent(MotionEvent event)
switch (event.getAction())
case MotionEvent.ACTION_DOWN:
lastTouchedX = event.getX();
scroller.forceFinished(true);
clearMessages();
break;
case MotionEvent.ACTION_MOVE:
int distanceX = (int) (event.getX() - lastTouchedX);
if (distanceX != 0)
startScrolling();
listener.onScroll(distanceX);
lastTouchedX = event.getX();
break;
//当手指离开控件时
if (!gestureDetector.onTouchEvent(event) && event.getAction() == MotionEvent.ACTION_UP)
justify();
return true;
/**
* 发送下一步消息,清楚之前的消息
* @param message
*/
private void setNextMessage(int message)
clearMessages();
animationHandler.sendEmptyMessage(message);
/**
* 清楚所有的what的消息列表
*/
private void clearMessages()
animationHandler.removeMessages(MESSAGE_SCROLL);
animationHandler.removeMessages(MESSAGE_JUSTIFY);
/**
* 滚动
* @param distance 距离
* @param time 时间
*/
public void scroll(int distance, int time)
scroller.forceFinished(true);
lastScrollX = 0;
scroller.startScroll(0, 0, distance, 0, time != 0 ? time : SCROLLING_DURATION);
setNextMessage(MESSAGE_SCROLL);
startScrolling();
/**
* 动画处理handler
*/
private Handler animationHandler = new Handler(new Handler.Callback()
@Override
public boolean handleMessage(Message msg)
scroller.computeScrollOffset();
int currX = scroller.getCurrX();
int delta = lastScrollX - currX;
lastScrollX = currX;
if (delta != 0)
listener.onScroll(delta);
// 滚动是不是完成时,涉及到最终Y,所以手动完成
if (Math.abs(currX - scroller.getFinalX()) < MIN_DELTA_FOR_SCROLLING)
lastScrollX = scroller.getFinalX();
scroller.forceFinished(true);
if (!scroller.isFinished())
animationHandler.sendEmptyMessage(msg.what);
else if (msg.what == MESSAGE_SCROLL)
justify();
else
finishScrolling();
return true;
);
/**
* 滚动停止时待校验
*/
private void justify()
listener.onJustify();
setNextMessage(MESSAGE_JUSTIFY);
/**
* 开始滚动
*/
private void startScrolling()
if (!isScrollingPerformed)
isScrollingPerformed = true;
listener.onStarted();
/**
* 滚动结束
*/
void finishScrolling()
if (isScrollingPerformed)
listener.onFinished();
isScrollingPerformed = false;
/**
* 滚动监听器接口
*/
public interface ScrollingListener
/**
* 正在滚动中回调
* @param distance 滚动的距离
*/
void onScroll(int distance);
/**
* 启动滚动时调用的回调函数
*/
void onStarted();
/**
* 校验完成后 执行完毕后回调
*/
void onFinished();
/**
* 滚动停止时待校验
*/
void onJustify();
然后在activity中:
/**
* 滚动回调接口
*/
RulerViewScroller.ScrollingListener scrollingListener = new RulerViewScroller.ScrollingListener()
/**
* 滚动开始
*/
@Override
public void onStarted()
isScrollingPerformed = true;
//滚动开始
if (null != onWheelListener)
onWheelListener.onScrollingStarted(RulerView.this);
/**
* 滚动中
* @param distance 滚动的距离
*/
@Override
public void onScroll(int distance)
doScroll(distance);
/**
* 滚动结束
*/
@Override
public void onFinished()
if (outOfRange())
return;
if (isScrollingPerformed)
//滚动结束
if (null != onWheelListener)
onWheelListener.onScrollingFinished(RulerView.this);
isScrollingPerformed = false;
scrollingOffset = 0;
invalidate();
/**
* 验证滚动是否在正确位置
*/
@Override
public void onJustify()
if (outOfRange())
return;
if (Math.abs(scrollingOffset) > RulerViewScroller.MIN_DELTA_FOR_SCROLLING)
if (scrollingOffset < -mScaleSpace / 2)
scroller.scroll(mScaleSpace + scrollingOffset, 0);
else if (scrollingOffset > mScaleSpace / 2)
scroller.scroll(scrollingOffset - mScaleSpace, 0);
else
scroller.scroll(scrollingOffset, 0);
;
/**
* 超出左右范围
* @return
*/
private boolean outOfRange()
//这个是越界后需要回滚的大小值
int outRange = 0;
if (mCurrentValue < mMinValue/mScaleBase)
outRange = (mCurrentValue - mMinValue/mScaleBase) * mScaleSpace;
else if (mCurrentValue > mMaxValue/mScaleBase)
outRange = (mCurrentValue - mMaxValue/mScaleBase) * mScaleSpace;
if (0 != outRange)
scrollingOffset = 0;
scroller.scroll(-outRange, 100);
return true;
return false;
/**
* 滚动中回调最新值
* @param delta
*/
private void doScroll(int delta)
scrollingOffset += delta;
int offsetCount = scrollingOffset / mScaleSpace;
if (0 != offsetCount)
// 显示在范围内
int oldValueIndex = Math.min(Math.max(mMinValue, mCurrentValue*mScaleBase), mMaxValue);
mCurrentValue -= offsetCount;
scrollingOffset -= offsetCount * mScaleSpace;
if (null != onWheelListener)
//回调通知最新的值
int valueIndex = Math.min(Math.max(mMinValue, mCurrentValue*mScaleBase), mMaxValue);
onWheelListener.onChanged(this, oldValueIndex + "",valueIndex+"");
invalidate();
private float mDownFocusX;
private float mDownFocusY;
private boolean isDisallowIntercept;
@Override
public boolean onTouchEvent(MotionEvent event)
if (!isEnabled())
return true;
switch (event.getAction())
case MotionEvent.ACTION_DOWN:
mDownFocusX = event.getX();
mDownFocusY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
if (!isDisallowIntercept && Math.abs(event.getY() - mDownFocusY) < Math.abs(event.getX() - mDownFocusX))
isDisallowIntercept = true;
if (getParent() != null)
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (getParent() != null)
getParent().requestDisallowInterceptTouchEvent(false);
isDisallowIntercept = false;
break;
return scroller.onTouchEvent(event);
private OnRulerViewScrollListener onWheelListener;
/**
* 添加滚动回调
* @param listener the listener
*/
public void setScrollingListener(OnRulerViewScrollListener listener)
onWheelListener = listener;
public interface OnRulerViewScrollListener<T>
/**
* 当更改选择的时候回调方法
* @param rulerView 状态更改的view
* @param oldValue 当前item的旧值
* @param newValue 当前item的新值
*/
void onChanged(RulerView rulerView, T oldValue, T newValue);
/**
* 滚动启动时调用的回调方法
* @param rulerView
*/
void onScrollingStarted(RulerView rulerView);
/**
* 滚动结束时调用的回调方法
* @param rulerView
*/
void onScrollingFinished(RulerView rulerView);
其中有些参考了网上实现方式并进行拓展以后就实现了下面的效果。
这里附上github:https://github.com/dalong982242260/AndroidRulerView
以上是关于Android自定义一个属于自己的刻度尺的主要内容,如果未能解决你的问题,请参考以下文章