package com.future.dispatch.utils.citypickerview.picker; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Typeface; import android.text.TextPaint; import android.text.TextUtils; import android.util.AttributeSet; import android.util.TypedValue; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.animation.DecelerateInterpolator; import androidx.annotation.Nullable; import com.xuexiang.xui.utils.ResUtils; import java.lang.ref.WeakReference; import java.math.BigDecimal; import uk.co.chrisjenx.calligraphy.HasTypeface; /** * 刻度尺控件 * * @author XUE * @since 2019/4/2 16:33 */ public class RulerView extends View implements HasTypeface { /** * 2个大刻度之间间距,默认为1 */ private int mScaleLimit = 1; /** * 尺子高度 */ private int mRulerHeight = 50; /** * 尺子和屏幕顶部以及结果之间的高度 */ private int mRulerToResultGap = mRulerHeight / 4; /** * 刻度平分多少份 */ private int mScaleCount = 10; /** * 刻度间距 */ private int mScaleGap = 10; /** * 刻度最小值 */ private int mMinScale = 0; /** * 第一次显示的刻度 */ private float mFirstScale = 50f; /** * 刻度最大值 */ private int mMaxScale = 100; /** * 背景颜色 */ private int mBgColor; /** * 小刻度的颜色 */ private int mSmallScaleColor; /** * 中刻度的颜色 */ private int mMidScaleColor; /** * 大刻度的颜色 */ private int mLargeScaleColor; /** * 刻度颜色 */ private int mScaleNumColor; /** * 结果值颜色 */ private int mResultNumColor; /** * kg颜色 */ private String mUnit = "kg"; /** * kg颜色 */ private int mUnitColor; /** * 小刻度粗细大小 */ private int mSmallScaleStroke = 2; /** * 中刻度粗细大小 */ private int mMidScaleStroke = 3; /** * 大刻度粗细大小 */ private int mLargeScaleStroke = 5; /** * 结果字体大小 */ private int mResultNumTextSize = 20; /** * 刻度字体大小 */ private int mScaleNumTextSize = 16; /** * 单位字体大小 */ private int mUnitTextSize = 13; /** * 是否显示刻度结果 */ private boolean mShowScaleResult = true; /** * 是否背景显示圆角 */ private boolean mIsBgRoundRect = true; /** * 圆角大小 */ private int mRoundRadius = 10; /** * 结果回调 */ private OnChooseResultListener mOnChooseResultListener; /** * 滑动选择刻度 */ private float mComputeScale = -1; /** * 当前刻度 */ public float mCurrentScale = mFirstScale; private ValueAnimator mValueAnimator; private VelocityTracker mVelocityTracker = VelocityTracker.obtain(); private String mResultText = String.valueOf(mFirstScale); private Paint mBgPaint; private Paint mSmallScalePaint; private Paint mMidScalePaint; private Paint mLagScalePaint; private TextPaint mScaleNumPaint; private TextPaint mResultNumPaint; private TextPaint mUnitPaint; private Rect mScaleNumRect; private Rect mResultNumRect; private Rect mKgRect; private RectF mBgRect; private int mHeight, mWidth; private int mSmallScaleHeight; private int mMidScaleHeight; private int mLagScaleHeight; private float mDownX; private float mMoveX = 0; private float mLastMoveX = 0; private boolean mIsUp = false; public RulerView(Context context) { this(context, null); } public RulerView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, com.xuexiang.xui.R.attr.RulerViewStyle); } public RulerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initAttrs(context, attrs, defStyleAttr); init(); } /** * 初始化属性 * * @param attrs * @param defStyleAttr */ private void initAttrs(Context context, AttributeSet attrs, int defStyleAttr) { TypedArray a = context.obtainStyledAttributes(attrs, com.xuexiang.xui.R.styleable.RulerView, defStyleAttr, 0); mScaleLimit = a.getInt(com.xuexiang.xui.R.styleable.RulerView_rv_scaleLimit, mScaleLimit); mRulerHeight = a.getDimensionPixelSize(com.xuexiang.xui.R.styleable.RulerView_rv_rulerHeight, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mRulerHeight, getResources().getDisplayMetrics())); mRulerToResultGap = a.getDimensionPixelSize(com.xuexiang.xui.R.styleable.RulerView_rv_rulerToResultGap, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mRulerToResultGap, getResources().getDisplayMetrics())); mScaleCount = a.getInt(com.xuexiang.xui.R.styleable.RulerView_rv_scaleCount, mScaleCount); mScaleGap = a.getDimensionPixelSize(com.xuexiang.xui.R.styleable.RulerView_rv_scaleGap, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mScaleGap, getResources().getDisplayMetrics())); mMinScale = a.getInt(com.xuexiang.xui.R.styleable.RulerView_rv_minScale, mMinScale) / mScaleLimit; mFirstScale = a.getFloat(com.xuexiang.xui.R.styleable.RulerView_rv_firstScale, mFirstScale) / mScaleLimit; mMaxScale = a.getInt(com.xuexiang.xui.R.styleable.RulerView_rv_maxScale, mMaxScale) / mScaleLimit; mBgColor = a.getColor(com.xuexiang.xui.R.styleable.RulerView_rv_bgColor, ResUtils.getColor(com.xuexiang.xui.R.color.default_ruler_view_bg_color)); mSmallScaleColor = a.getColor(com.xuexiang.xui.R.styleable.RulerView_rv_smallScaleColor, ResUtils.getColor(com.xuexiang.xui.R.color.default_ruler_view_small_scale_color)); mMidScaleColor = a.getColor(com.xuexiang.xui.R.styleable.RulerView_rv_midScaleColor, ResUtils.getColor(com.xuexiang.xui.R.color.default_ruler_view_mid_scale_color)); mLargeScaleColor = a.getColor(com.xuexiang.xui.R.styleable.RulerView_rv_largeScaleColor, ResUtils.getColor(com.xuexiang.xui.R.color.default_ruler_view_large_scale_color)); mScaleNumColor = a.getColor(com.xuexiang.xui.R.styleable.RulerView_rv_scaleNumColor, ResUtils.getColor(com.xuexiang.xui.R.color.default_ruler_view_scale_num_color)); mResultNumColor = a.getColor(com.xuexiang.xui.R.styleable.RulerView_rv_resultNumColor, ResUtils.getColor(com.xuexiang.xui.R.color.default_ruler_view_result_num_color)); mUnitColor = a.getColor(com.xuexiang.xui.R.styleable.RulerView_rv_unitColor, ResUtils.getColor(com.xuexiang.xui.R.color.default_ruler_view_unit_color)); String tempUnit = mUnit; mUnit = a.getString(com.xuexiang.xui.R.styleable.RulerView_rv_unit); if (TextUtils.isEmpty(mUnit)) { mUnit = tempUnit; } mSmallScaleStroke = a.getDimensionPixelSize(com.xuexiang.xui.R.styleable.RulerView_rv_smallScaleStroke, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mSmallScaleStroke, getResources().getDisplayMetrics())); mMidScaleStroke = a.getDimensionPixelSize(com.xuexiang.xui.R.styleable.RulerView_rv_midScaleStroke, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mMidScaleStroke, getResources().getDisplayMetrics())); mLargeScaleStroke = a.getDimensionPixelSize(com.xuexiang.xui.R.styleable.RulerView_rv_largeScaleStroke, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mLargeScaleStroke, getResources().getDisplayMetrics())); mResultNumTextSize = a.getDimensionPixelSize(com.xuexiang.xui.R.styleable.RulerView_rv_resultNumTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mResultNumTextSize, getResources().getDisplayMetrics())); mScaleNumTextSize = a.getDimensionPixelSize(com.xuexiang.xui.R.styleable.RulerView_rv_scaleNumTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mScaleNumTextSize, getResources().getDisplayMetrics())); mUnitTextSize = a.getDimensionPixelSize(com.xuexiang.xui.R.styleable.RulerView_rv_unitTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mUnitTextSize, getResources().getDisplayMetrics())); mShowScaleResult = a.getBoolean(com.xuexiang.xui.R.styleable.RulerView_rv_showScaleResult, mShowScaleResult); mIsBgRoundRect = a.getBoolean(com.xuexiang.xui.R.styleable.RulerView_rv_isBgRoundRect, mIsBgRoundRect); mRoundRadius = a.getDimensionPixelSize(com.xuexiang.xui.R.styleable.RulerView_rv_roundRadius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mRoundRadius, getResources().getDisplayMetrics())); a.recycle(); } private void init() { mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mSmallScalePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mMidScalePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mLagScalePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mScaleNumPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); mResultNumPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); mUnitPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); mBgPaint.setColor(mBgColor); mSmallScalePaint.setColor(mSmallScaleColor); mMidScalePaint.setColor(mMidScaleColor); mLagScalePaint.setColor(mLargeScaleColor); mScaleNumPaint.setColor(mScaleNumColor); mResultNumPaint.setColor(mResultNumColor); mUnitPaint.setColor(mUnitColor); mResultNumPaint.setStyle(Paint.Style.FILL); mUnitPaint.setStyle(Paint.Style.FILL); mBgPaint.setStyle(Paint.Style.FILL); mSmallScalePaint.setStyle(Paint.Style.FILL); mMidScalePaint.setStyle(Paint.Style.FILL); mLagScalePaint.setStyle(Paint.Style.FILL); mLagScalePaint.setStrokeCap(Paint.Cap.ROUND); mMidScalePaint.setStrokeCap(Paint.Cap.ROUND); mSmallScalePaint.setStrokeCap(Paint.Cap.ROUND); mSmallScalePaint.setStrokeWidth(mSmallScaleStroke); mMidScalePaint.setStrokeWidth(mMidScaleStroke); mLagScalePaint.setStrokeWidth(mLargeScaleStroke); mResultNumPaint.setTextSize(mResultNumTextSize); mUnitPaint.setTextSize(mUnitTextSize); mScaleNumPaint.setTextSize(mScaleNumTextSize); mBgRect = new RectF(); mResultNumRect = new Rect(); mScaleNumRect = new Rect(); mKgRect = new Rect(); mResultNumPaint.getTextBounds(mResultText, 0, mResultText.length(), mResultNumRect); mUnitPaint.getTextBounds(mResultText, 0, 1, mKgRect); mSmallScaleHeight = mRulerHeight / 4; mMidScaleHeight = mRulerHeight / 2; mLagScaleHeight = mRulerHeight / 2 + 5; mValueAnimator = new ValueAnimator(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int heightModule = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); switch (heightModule) { case MeasureSpec.AT_MOST: mHeight = mRulerHeight + (mShowScaleResult ? mResultNumRect.height() : 0) + mRulerToResultGap * 2 + getPaddingTop() + getPaddingBottom(); break; case MeasureSpec.UNSPECIFIED: case MeasureSpec.EXACTLY: mHeight = heightSize + getPaddingTop() + getPaddingBottom(); break; default: break; } mWidth = widthSize + getPaddingLeft() + getPaddingRight(); setMeasuredDimension(mWidth, mHeight); } @Override protected void onDraw(Canvas canvas) { drawBg(canvas); drawScaleAndNum(canvas); drawResultText(canvas, mResultText); } @Override public boolean onTouchEvent(MotionEvent event) { if (getParent() != null) { //拦截事件,不让父布局获取 getParent().requestDisallowInterceptTouchEvent(true); } float currentX = event.getX(); mIsUp = false; mVelocityTracker.computeCurrentVelocity(500); mVelocityTracker.addMovement(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //按下时如果属性动画还没执行完,就终止,记录下当前按下点的位置 if (mValueAnimator != null && mValueAnimator.isRunning()) { mValueAnimator.end(); mValueAnimator.cancel(); } mDownX = event.getX(); break; case MotionEvent.ACTION_MOVE: //滑动时候,通过假设的滑动距离,做超出左边界以及右边界的限制。 mMoveX = currentX - mDownX + mLastMoveX; if (mMoveX >= mWidth / 2) { mMoveX = mWidth / 2; } else if (mMoveX <= getWhichScaleMoveX(mMaxScale)) { mMoveX = getWhichScaleMoveX(mMaxScale); } break; case MotionEvent.ACTION_UP: //手指抬起时候制造惯性滑动 mLastMoveX = mMoveX; int xVelocity = (int) mVelocityTracker.getXVelocity(); autoVelocityScroll(xVelocity); mVelocityTracker.clear(); break; default: break; } invalidate(); return true; } private void autoVelocityScroll(int xVelocity) { //惯性滑动的代码,速率和滑动距离,以及滑动时间需要控制的很好,应该网上已经有关于这方面的算法了吧。。这里是经过N次测试调节出来的惯性滑动 if (Math.abs(xVelocity) < 50) { mIsUp = true; return; } if (mValueAnimator.isRunning()) { return; } mValueAnimator = ValueAnimator.ofInt(0, xVelocity / 20).setDuration(Math.abs(xVelocity / 10)); mValueAnimator.setInterpolator(new DecelerateInterpolator()); mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mMoveX += (int) animation.getAnimatedValue(); if (mMoveX >= mWidth / 2) { mMoveX = mWidth / 2; } else if (mMoveX <= getWhichScaleMoveX(mMaxScale)) { mMoveX = getWhichScaleMoveX(mMaxScale); } mLastMoveX = mMoveX; invalidate(); } }); mValueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mIsUp = true; invalidate(); } }); mValueAnimator.start(); } private float getWhichScaleMoveX(float scale) { return mWidth / 2 - mScaleGap * mScaleCount * (scale - mMinScale); } private void drawScaleAndNum(Canvas canvas) { canvas.translate(0, (mShowScaleResult ? mResultNumRect.height() : 0) + mRulerToResultGap);//移动画布到结果值的下面 int num1;//确定刻度位置 float num2; if (mFirstScale != -1) { //第一次进来的时候计算出默认刻度对应的假设滑动的距离moveX mMoveX = getWhichScaleMoveX(mFirstScale); //如果设置了默认滑动位置,计算出需要滑动的距离 mLastMoveX = mMoveX; mFirstScale = -1; //将结果置为-1,下次不再计算初始位置 } if (mComputeScale != -1) {//弹性滑动到目标刻度 mLastMoveX = mMoveX; if (mValueAnimator != null && !mValueAnimator.isRunning()) { mValueAnimator = ValueAnimator.ofFloat(getWhichScaleMoveX(mCurrentScale), getWhichScaleMoveX(mComputeScale)); mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mMoveX = (float) animation.getAnimatedValue(); mLastMoveX = mMoveX; invalidate(); } }); mValueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); //这里是滑动结束时候回调给使用者的结果值 mComputeScale = -1; } }); mValueAnimator.setDuration(Math.abs((long) ((getWhichScaleMoveX(mComputeScale) - getWhichScaleMoveX(mCurrentScale)) / 100))); mValueAnimator.start(); } } num1 = -(int) (mMoveX / mScaleGap); //滑动刻度的整数部分 num2 = (mMoveX % mScaleGap); //滑动刻度的小数部分 canvas.save(); //保存当前画布 int rulerRight = 0; //准备开始绘制当前屏幕,从最左面开始 if (mIsUp) { //这部分代码主要是计算手指抬起时,惯性滑动结束时,刻度需要停留的位置 num2 = ((mMoveX - mWidth / 2 % mScaleGap) % mScaleGap); //计算滑动位置距离整点刻度的小数部分距离 if (num2 <= 0) { num2 = mScaleGap - Math.abs(num2); } int leftScroll = (int) Math.abs(num2); //当前滑动位置距离左边整点刻度的距离 int rightScroll = (int) (mScaleGap - Math.abs(num2)); //当前滑动位置距离右边整点刻度的距离 float moveX2 = num2 <= mScaleGap / 2 ? mMoveX - leftScroll : mMoveX + rightScroll; //最终计算出当前位置到整点刻度位置需要滑动的距离 if (mValueAnimator != null && !mValueAnimator.isRunning()) { //手指抬起,并且当前没有惯性滑动在进行,创建一个惯性滑动 mValueAnimator = ValueAnimator.ofFloat(mMoveX, moveX2); mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mMoveX = (float) animation.getAnimatedValue(); //不断滑动去更新新的位置 mLastMoveX = mMoveX; invalidate(); } }); mValueAnimator.addListener(new AnimatorListenerAdapter() { //增加一个监听,用来返回给使用者滑动结束后的最终结果刻度值 @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); //这里是滑动结束时候回调给使用者的结果值 if (mOnChooseResultListener != null) { mOnChooseResultListener.onEndResult(mResultText); } } }); mValueAnimator.setDuration(300); mValueAnimator.start(); mIsUp = false; } //重新计算当前滑动位置的整数以及小数位置 num1 = (int) -(mMoveX / mScaleGap); num2 = (mMoveX % mScaleGap); } //不加该偏移的话,滑动时刻度不会落在0~1之间只会落在整数上面,其实这个都能设置一种模式了,毕竟初衷就是指针不会落在小数上面 canvas.translate(num2, 0); //这里是滑动时候不断回调给使用者的结果值 mCurrentScale = new WeakReference<>(new BigDecimal(((mWidth / 2 - mMoveX) / (mScaleGap * mScaleCount) + mMinScale) * mScaleLimit)).get().setScale(1, BigDecimal.ROUND_HALF_UP).floatValue(); mResultText = String.valueOf(mCurrentScale); if (mOnChooseResultListener != null) { mOnChooseResultListener.onScrollResult(mResultText); //接口不断回调给使用者结果值 } //绘制当前屏幕可见刻度,不需要裁剪屏幕,while循环只会执行·屏幕宽度/刻度宽度·次,大部分的绘制都是if(curDis= 0 && rulerRight < mMoveX - mScaleGap) || mWidth / 2 - rulerRight <= getWhichScaleMoveX(mMaxScale + 1) - mMoveX) { //当滑动出范围的话,不绘制,去除左右边界 } else { //绘制刻度,绘制刻度数字 canvas.drawLine(0, 0, 0, mMidScaleHeight, mMidScalePaint); mScaleNumPaint.getTextBounds(num1 / mScaleGap + mMinScale + "", 0, (num1 / mScaleGap + mMinScale + "").length(), mScaleNumRect); canvas.drawText((num1 / mScaleCount + mMinScale) * mScaleLimit + "", -mScaleNumRect.width() / 2, mLagScaleHeight + (mRulerHeight - mLagScaleHeight) / 2 + mScaleNumRect.height(), mScaleNumPaint); } } else { //绘制小数刻度 if ((mMoveX >= 0 && rulerRight < mMoveX) || mWidth / 2 - rulerRight < getWhichScaleMoveX(mMaxScale) - mMoveX) { //当滑动出范围的话,不绘制,去除左右边界 } else { //绘制小数刻度 canvas.drawLine(0, 0, 0, mSmallScaleHeight, mSmallScalePaint); } } ++num1; //刻度加1 rulerRight += mScaleGap; //绘制屏幕的距离在原有基础上+1个刻度间距 canvas.translate(mScaleGap, 0); //移动画布到下一个刻度 } canvas.restore(); //绘制屏幕中间用来选中刻度的最大刻度 canvas.drawLine(mWidth / 2, 0, mWidth / 2, mLagScaleHeight, mLagScalePaint); } //绘制上面的结果 结果值+单位 private void drawResultText(Canvas canvas, String resultText) { if (!mShowScaleResult) { //判断用户是否设置需要显示当前刻度值,如果否则取消绘制 return; } canvas.translate(0, -mResultNumRect.height() - mRulerToResultGap / 2); //移动画布到正确的位置来绘制结果值 mResultNumPaint.getTextBounds(resultText, 0, resultText.length(), mResultNumRect); canvas.drawText(resultText, mWidth / 2 - mResultNumRect.width() / 2, mResultNumRect.height(), //绘制当前刻度结果值 mResultNumPaint); int resultNumRight = mWidth / 2 + mResultNumRect.width() / 2 + 10; canvas.drawText(mUnit, resultNumRight, mKgRect.height() + 2, mUnitPaint); //在当前刻度结果值的又面10px的位置绘制单位 } private void drawBg(Canvas canvas) { mBgRect.set(0, 0, mWidth, mHeight); if (mIsBgRoundRect) { //椭圆的用于圆形角x-radius canvas.drawRoundRect(mBgRect, mRoundRadius, mRoundRadius, mBgPaint); } else { canvas.drawRect(mBgRect, mBgPaint); } } private void computeScrollTo(float scale) { scale = scale / mScaleLimit; if (scale < mMinScale || scale > mMaxScale) { return; } mComputeScale = scale; invalidate(); } @Override public void setTypeface(Typeface typeface) { if (mResultNumPaint != null) { mResultNumPaint.setTypeface(typeface); } if (mUnitPaint != null) { mUnitPaint.setTypeface(typeface); } if (mScaleNumPaint != null) { mScaleNumPaint.setTypeface(typeface); } } /** * 选择结果监听 */ public interface OnChooseResultListener { /** * 滑动选择结束 * * @param result */ void onEndResult(String result); /** * 开始滑动选择 * * @param result */ void onScrollResult(String result); } public void setRulerHeight(int rulerHeight) { this.mRulerHeight = rulerHeight; invalidate(); } public void setRulerToResultGap(int rulerToResultGap) { this.mRulerToResultGap = rulerToResultGap; invalidate(); } public void setScaleCount(int scaleCount) { this.mScaleCount = scaleCount; invalidate(); } public void setScaleGap(int scaleGap) { this.mScaleGap = scaleGap; invalidate(); } public void setMinScale(int minScale) { this.mMinScale = minScale; invalidate(); } public void setFirstScale(float firstScale) { this.mFirstScale = firstScale; invalidate(); } public void setMaxScale(int maxScale) { this.mMaxScale = maxScale; invalidate(); } public void setBgColor(int bgColor) { this.mBgColor = bgColor; invalidate(); } public void setSmallScaleColor(int smallScaleColor) { this.mSmallScaleColor = smallScaleColor; invalidate(); } public void setMidScaleColor(int midScaleColor) { this.mMidScaleColor = midScaleColor; invalidate(); } public void setLargeScaleColor(int largeScaleColor) { this.mLargeScaleColor = largeScaleColor; } public void setScaleNumColor(int scaleNumColor) { this.mScaleNumColor = scaleNumColor; invalidate(); } public void setResultNumColor(int resultNumColor) { this.mResultNumColor = resultNumColor; invalidate(); } public void setUnit(String unit) { this.mUnit = unit; invalidate(); } public void setUnitColor(int unitColor) { this.mUnitColor = unitColor; invalidate(); } public void setSmallScaleStroke(int smallScaleStroke) { this.mSmallScaleStroke = smallScaleStroke; invalidate(); } public void setMidScaleStroke(int midScaleStroke) { this.mMidScaleStroke = midScaleStroke; invalidate(); } public void setLargeScaleStroke(int largeScaleStroke) { this.mLargeScaleStroke = largeScaleStroke; invalidate(); } public void setResultNumTextSize(int resultNumTextSize) { this.mResultNumTextSize = resultNumTextSize; invalidate(); } public void setScaleNumTextSize(int scaleNumTextSize) { this.mScaleNumTextSize = scaleNumTextSize; invalidate(); } public void setUnitTextSize(int unitTextSize) { this.mUnitTextSize = unitTextSize; invalidate(); } public void setShowScaleResult(boolean showScaleResult) { this.mShowScaleResult = showScaleResult; invalidate(); } public void setIsBgRoundRect(boolean bgRoundRect) { mIsBgRoundRect = bgRoundRect; invalidate(); } public void setScaleLimit(int scaleLimit) { this.mScaleLimit = scaleLimit; invalidate(); } /** * 设置刻度尺的值 * * @param value */ public void setCurrentValue(float value) { computeScrollTo(value); } /** * 获取当前刻度尺的刻度 * * @return */ public float getCurrentValue() { return mCurrentScale; } /** * 获取选择值 * * @return */ public String getSelectValue() { return mResultText; } /** * 设置选择监听 * * @param onChooseResultListener * @return */ public RulerView setOnChooseResultListener(OnChooseResultListener onChooseResultListener) { this.mOnChooseResultListener = onChooseResultListener; return this; } }