Android自定义View之滑动取值条

来源:互联网 发布:图片不停绕中心旋转js 编辑:程序博客网 时间:2024/06/12 00:06

Android自定义View之滑动取值条

1 : 需求
可自定义更改滑动条的样式(本功能实现两种样式)
联动方式 : 滑块上更新的值通过回调给Edittext; 在Edittext上输入值,更新滑动条的游标的位置和值
高度复合性: 可根据需求,自初始化值,及返回值的调整,显示精度的可调整性
,超过滑动范围的可调整性
滑动取值条的取值方式: 可滑动,可点击
当值过大时,取值条上的值根据像素比例进行相应的缩放,使其显示完全

2: 实现

public CustomTakeValueArticle(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init(context);    }    public CustomTakeValueArticle(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }

上面的代码这里只构造了两个方法

初始化init(Context context)的实现如下:

  /**     * 初始化     *     * @param context     */    private void init(Context context) {        mTrunkBmp = BitmapFactory.decodeResource(getResources(), R.drawable.cursor_line_red);        mTrunkBmpDeep = BitmapFactory.decodeResource(getResources(), R.drawable.cursor_line_red_deep);        mCursorBmp = BitmapFactory.decodeResource(getResources(), R.drawable.red_cursor);        matrix = new Matrix();        matrixDeep = new Matrix();        mTrunkHight = mTrunkBmp.getHeight();        mCursorWidth = mCursorBmp.getWidth();        mCursorHight = mCursorBmp.getHeight();        mTrunkMarginTop = dip2px(context, TRUNKMARGINTOP);        mTextCursorSpace = dip2px(context, TEXT_CURSOR_SPACE);        mCursorTextSize = sp2px(context, TEXTSIZE);        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();        mClickTimeout = ViewConfiguration.getPressedStateDuration() + ViewConfiguration.getTapTimeout();        mLineWidth = dip2px(context, LINEWIDTH);        mPaint = new Paint();        mPaint.setColor(Color.RED);// 设置红色        mPaint.setStyle(Paint.Style.FILL);        mPaint.setTextAlign(Paint.Align.CENTER);        mPaint.setTextSize(mCursorTextSize);        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();        mTextHight = (int) (fontMetrics.descent - fontMetrics.ascent + 0.5f);    }

这里对刻度杆滑动,未滑动,游标图的bitmap进行初始化,相关矩阵,画笔等初始化

重写onDraw方法

    /**     * 重写onDraw方法     *     * @param canvas     */    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        mScaling = (getWidth() - getPaddingRight() - getPaddingLeft() - mCursorWidth)                / (getXAxisEnd() - getXAxisStart());        if (ISCENTERVERTICALTRUNK) {            mTrunkMarginTop = (getHeight() - mTrunkHight) / 2.0f;        }        if (dstbmp != null)            dstbmp.recycle();        dstbmp = null;        drawTrunk(canvas, mTrunkMarginTop);        drawCursor(canvas);    }

这里在重写onDraw方法时取实际坐标转换为像素坐标的比例 mScaling
,刻度杆的上边界像素坐标mTrunkMarginTop,再进行重写drawTrunk(刻度杆),drawCursor(游标)的方法.

drawTrunk(刻度杆)的方法如下:

   /**     * 绘制刻度条主干     *     * @param canvas     */    private void drawTrunk(Canvas canvas, float mTrunkMarginTop) {        int leftbmp = getPaddingLeft();        int topBoundary = (int) (mTrunkMarginTop + 0.5f);        int widthbmp = getWidth() - getPaddingLeft() - getPaddingRight();        float scaw = widthbmp * 1.0f / (mTrunkBmp.getWidth());        matrix.setScale(scaw, 1.0f);        /**         * 绘制未选中的值刻度线         */        if (dstbmp == null)            dstbmp = Bitmap.createBitmap(mTrunkBmp, 0, 0, mTrunkBmp.getWidth(), mTrunkBmp.getHeight(), matrix, true);        canvas.drawBitmap(dstbmp, leftbmp, topBoundary, null);        /**         * 绘制选中的值刻度线         */        if (x - mXAxisStart >= 0 && mXAxisEnd - x >= 0) {            scaw = (float) (getWidthForXValue() * 1.0f / mTrunkBmpDeep.getWidth());        } else if (mXAxisEnd - x < 0) {            scaw = (float) (getWidthForXValue() * 1.0f / mTrunkBmpDeep.getWidth());        } else {            scaw = mCursorWidth / 2.0f / mTrunkBmpDeep.getWidth();        }        float scaH = mTrunkBmp.getHeight() * 1.0f / mTrunkBmpDeep.getHeight();        matrixDeep.setScale(scaw, scaH);        Bitmap dstbmpdeep = Bitmap.createBitmap(mTrunkBmpDeep, 0, 0, mTrunkBmpDeep.getWidth(),                mTrunkBmpDeep.getHeight(), matrixDeep, true);        canvas.drawBitmap(dstbmpdeep, leftbmp, topBoundary, null);        /**         * 绘制起始值和结束值(isInteger保留整数,否则精度)         */        double tempX = getXForXvalue(mXAxisEnd);        mPaint.setColor(getTrunkTextColor());        String mEnd;        if (isInteger) {//保持整形            mEnd = String.valueOf((int) mXAxisEnd);        } else {            BigDecimal bd = new BigDecimal(mXAxisEnd);            bd = bd.setScale(precision, BigDecimal.ROUND_HALF_DOWN);            mEnd = String.valueOf(bd.doubleValue());        }        refitText(mEnd, computeMaxStringWidth(mEnd));        canvas.drawText(mEnd, (float) tempX,                mTrunkHight / 2.0f + mCursorHight + mTextHight + mTextHight / 2.0f,                mPaint);        String mStart;        if (isInteger) {//保持整形            mStart = String.valueOf((int) mXAxisStart);        } else {            BigDecimal bd = new BigDecimal(mXAxisStart);            bd = bd.setScale(precision, BigDecimal.ROUND_HALF_UP);            mStart = String.valueOf(bd.doubleValue());        }        double tempSX = getXForXvalue(mXAxisStart);        mPaint.setColor(getTrunkTextColor());        refitText(mStart, computeMaxStringWidth(mStart));        canvas.drawText(mStart, (float) tempSX,                mTrunkHight / 2.0f + mCursorHight + mTextHight + mTextHight / 2.0f,                mPaint);        /**         * 绘制标记(起始位置和结束位置)         */        float lineW = (mLineWidth + 0.5f);        float tempLSX = (float) getXForXvalue(mXAxisStart);        mPaint.setColor(getTrunkTextColor());        canvas.drawRect(tempLSX, mTrunkMarginTop, tempLSX + lineW, mTrunkMarginTop + mTrunkHight, mPaint);        float tempLEX = (float) getXForXvalue(mXAxisEnd);        mPaint.setColor(getTrunkTextColor());        canvas.drawRect(tempLEX, mTrunkMarginTop, tempLEX + lineW, mTrunkMarginTop + mTrunkHight, mPaint);    }

绘制刻度杆主干只要绘制未选中的值刻度线,选中的值刻度线,以及绘制起始值和结束值,根据isInteger来设置是否保持整形还是精度,精度值根据precision参数来设置

绘制游标drawCursor方法如下:

/**     * 绘制游标     *     * @param canvas     */    private void drawCursor(Canvas canvas) {        /**         * 绘制游标图片         */        canvas.drawBitmap(mCursorBmp, (int) (getXLocation() - mCursorWidth / 2.0f + 0.5f),                (int) (mTrunkMarginTop + mTrunkHight / 2.0f - mCursorHight / 2.0f + 0.5f), null);        /**         * 绘制游标文字         */        if (isInteger) {//点差策略            scrollValue = String.valueOf(((int) value));        } else {            BigDecimal bd = new BigDecimal(scrollValue);            bd = bd.setScale(precision, BigDecimal.ROUND_HALF_UP);            scrollValue = String.valueOf(bd.doubleValue());        }        mPaint.setColor(getCursorTextColor());        refitText(scrollValue, computeMaxStringWidth(scrollValue));        canvas.drawText(scrollValue, (int) (getXLocation() + 0.5f),                (int) (mTrunkMarginTop - mCursorHight / 2.0f + mTrunkHight / 2.0f + 0.5f - mTextCursorSpace),                mPaint);    }

该方法里主要是绘制游标图片和绘制游标文字

完整的View代码如下:

package com.example.administrator.myapplication;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Rect;import android.text.Layout;import android.text.TextPaint;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.widget.TextView;import java.math.BigDecimal;/** * Created by Linhailin on 2017/2/13. */public class CustomTakeValueArticle extends View {    /**     * 红色(游标和范围)颜色值     */    private final int COLOR_PROFIT_LINE = getResources().getColor(R.color.scroll_bar_line_red);    private final int COLOR_PROFIT_TEXT = getResources().getColor(R.color.scroll_bar_text_red_label);    /**     * 绿色(游标和范围)颜色值     */    private final int COLOR_LOSS_LINE = getResources().getColor(R.color.scroll_bar_line_bule);    private final int COLOR_LOSS_TEXT = getResources().getColor(R.color.scroll_bar_text_bule_label);    /**     * 滑动游标图片     */    private Bitmap mCursorBmp;    /**     * 主干相关     */    private Bitmap mTrunkBmp;    private Matrix matrix;    private Bitmap dstbmp;    private Matrix matrixDeep;    private Bitmap mTrunkBmpDeep;    /**     * 画笔     */    private Paint mPaint;    /**     * 文字大小(PX)     */    private float mCursorTextSize = 0;    /**     * 刻度杆的上边界像素坐标     */    private float mTrunkMarginTop = 20;    /**     * 横坐标开始点坐标     */    private double mXAxisStart;    /**     * 横坐标结束点坐标     */    private double mXAxisEnd;    /**     * 实际坐标转换为像素坐标的比例     */    private double mScaling;    /**     * 游标的宽度     */    private float mCursorWidth = 0;    /**     * 游标的高度     */    private int mCursorHight = 0;    /**     * 刻度杆的高度     */    private int mTrunkHight = 0;    /**     * 刻度杆的上边界(DP)     */    private float TRUNKMARGINTOP = 15;    /**     * 刻度杆是否居中     */    private boolean ISCENTERVERTICALTRUNK = true;    private double x = 0;    /**     * 游标与文字之间的间隔     */    private int mTextCursorSpace = 0;    /**     * 游标与文字之间的间隔(DP)     */    private final float TEXT_CURSOR_SPACE = 0.5f;    /**     * 文字大小(SP)     */    private int TEXTSIZE = 10;    /**     * 文字的高度     */    private float mTextHight;    /**     * 是止盈     */    private boolean isProfit = true;    private OnScrollListener onScrollListener;    private OnClickListener onClickListener;    private boolean noSetX = true;    /**     * 刻度线的粗细     */    private float mLineWidth = 0;    /**     * 刻度线的粗细(DP)     */    private final int LINEWIDTH = 1;    /**     * 当前游标上的数值     */    private double value;    /**     * 当前游标上的文字     */    private String scrollValue = "0";    /**     * 触摸滑动计数,超过,这认为不是点击事件     */    private int mTouchSlop = 0;    /**     * 触摸时间,超过,则认为不是点击事件     */    private int mClickTimeout = 0;    /**     * 值的精度     */    private int precision;    /**     * 设置类型(是否需要保持精度还是整形)     */    private Boolean isInteger;    public CustomTakeValueArticle(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init(context);    }    public CustomTakeValueArticle(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    /**     * 初始化     *     * @param context     */    private void init(Context context) {        mTrunkBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_red);        mTrunkBmpDeep = BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_red_deep);        mCursorBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.red_cursor);        matrix = new Matrix();        matrixDeep = new Matrix();        mTrunkHight = mTrunkBmp.getHeight();        mCursorWidth = mCursorBmp.getWidth();        mCursorHight = mCursorBmp.getHeight();        mTrunkMarginTop = dip2px(context, TRUNKMARGINTOP);        mTextCursorSpace = dip2px(context, TEXT_CURSOR_SPACE);        mCursorTextSize = sp2px(context, TEXTSIZE);        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();        mClickTimeout = ViewConfiguration.getPressedStateDuration() + ViewConfiguration.getTapTimeout();        mLineWidth = dip2px(context, LINEWIDTH);        mPaint = new Paint();        mPaint.setColor(Color.RED);// 设置红色        mPaint.setStyle(Paint.Style.FILL);        mPaint.setTextAlign(Paint.Align.CENTER);        mPaint.setTextSize(mCursorTextSize);        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();        mTextHight = (int) (fontMetrics.descent - fontMetrics.ascent + 0.5f);    }    /**     * 重写onDraw方法     *     * @param canvas     */    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        mScaling = (getWidth() - getPaddingRight() - getPaddingLeft() - mCursorWidth)                / (getXAxisEnd() - getXAxisStart());        if (ISCENTERVERTICALTRUNK) {            mTrunkMarginTop = (getHeight() - mTrunkHight) / 2.0f;        }        if (dstbmp != null)            dstbmp.recycle();        dstbmp = null;        drawTrunk(canvas, mTrunkMarginTop);        drawCursor(canvas);    }    /**     * 绘制刻度条主干     *     * @param canvas     */    private void drawTrunk(Canvas canvas, float mTrunkMarginTop) {        int leftbmp = getPaddingLeft();        int topBoundary = (int) (mTrunkMarginTop + 0.5f);        int widthbmp = getWidth() - getPaddingLeft() - getPaddingRight();        float scaw = widthbmp * 1.0f / (mTrunkBmp.getWidth());        matrix.setScale(scaw, 1.0f);        /**         * 绘制未选中的值刻度线         */        if (dstbmp == null)            dstbmp = Bitmap.createBitmap(mTrunkBmp, 0, 0, mTrunkBmp.getWidth(), mTrunkBmp.getHeight(), matrix, true);        canvas.drawBitmap(dstbmp, leftbmp, topBoundary, null);        /**         * 绘制选中的值刻度线         */        if (x - mXAxisStart >= 0 && mXAxisEnd - x >= 0) {            scaw = (float) (getWidthForXValue() * 1.0f / mTrunkBmpDeep.getWidth());        } else if (mXAxisEnd - x < 0) {            scaw = (float) (getWidthForXValue() * 1.0f / mTrunkBmpDeep.getWidth());        } else {            scaw = mCursorWidth / 2.0f / mTrunkBmpDeep.getWidth();        }        float scaH = mTrunkBmp.getHeight() * 1.0f / mTrunkBmpDeep.getHeight();        matrixDeep.setScale(scaw, scaH);        Bitmap dstbmpdeep = Bitmap.createBitmap(mTrunkBmpDeep, 0, 0, mTrunkBmpDeep.getWidth(),                mTrunkBmpDeep.getHeight(), matrixDeep, true);        canvas.drawBitmap(dstbmpdeep, leftbmp, topBoundary, null);        /**         * 绘制起始值和结束值(isInteger保留整数,否则精度)         */        double tempX = getXForXvalue(mXAxisEnd);        mPaint.setColor(getTrunkTextColor());        String mEnd;        if (isInteger) {//保持整形            mEnd = String.valueOf((int) mXAxisEnd);        } else {            BigDecimal bd = new BigDecimal(mXAxisEnd);            bd = bd.setScale(precision, BigDecimal.ROUND_HALF_DOWN);            mEnd = String.valueOf(bd.doubleValue());        }        refitText(mEnd, computeMaxStringWidth(mEnd));        canvas.drawText(mEnd, (float) tempX,                mTrunkHight / 2.0f + mCursorHight + mTextHight + mTextHight / 2.0f,                mPaint);        String mStart;        if (isInteger) {//保持整形            mStart = String.valueOf((int) mXAxisStart);        } else {            BigDecimal bd = new BigDecimal(mXAxisStart);            bd = bd.setScale(precision, BigDecimal.ROUND_HALF_UP);            mStart = String.valueOf(bd.doubleValue());        }        double tempSX = getXForXvalue(mXAxisStart);        mPaint.setColor(getTrunkTextColor());        refitText(mStart, computeMaxStringWidth(mStart));        canvas.drawText(mStart, (float) tempSX,                mTrunkHight / 2.0f + mCursorHight + mTextHight + mTextHight / 2.0f,                mPaint);        /**         * 绘制标记(起始位置和结束位置)         */        float lineW = (mLineWidth + 0.5f);        float tempLSX = (float) getXForXvalue(mXAxisStart);        mPaint.setColor(getTrunkTextColor());        canvas.drawRect(tempLSX, mTrunkMarginTop, tempLSX + lineW, mTrunkMarginTop + mTrunkHight, mPaint);        float tempLEX = (float) getXForXvalue(mXAxisEnd);        mPaint.setColor(getTrunkTextColor());        canvas.drawRect(tempLEX, mTrunkMarginTop, tempLEX + lineW, mTrunkMarginTop + mTrunkHight, mPaint);    }    /**     * 绘制游标     *     * @param canvas     */    private void drawCursor(Canvas canvas) {        /**         * 绘制游标图片         */        canvas.drawBitmap(mCursorBmp, (int) (getXLocation() - mCursorWidth / 2.0f + 0.5f),                (int) (mTrunkMarginTop + mTrunkHight / 2.0f - mCursorHight / 2.0f + 0.5f), null);        /**         * 绘制游标文字         */        if (isInteger) {//点差策略            scrollValue = String.valueOf(((int) value));        } else {            BigDecimal bd = new BigDecimal(scrollValue);            bd = bd.setScale(precision, BigDecimal.ROUND_HALF_UP);            scrollValue = String.valueOf(bd.doubleValue());        }        mPaint.setColor(getCursorTextColor());        refitText(scrollValue, computeMaxStringWidth(scrollValue));        canvas.drawText(scrollValue, (int) (getXLocation() + 0.5f),                (int) (mTrunkMarginTop - mCursorHight / 2.0f + mTrunkHight / 2.0f + 0.5f - mTextCursorSpace),                mPaint);    }    /**     * 设置游标图片     */    public void setCursorBmp(Bitmap mCursorBitmap) {        this.mCursorBmp = mCursorBitmap;    }    /**     * 设置刻度未选中图片     */    public void setTrunkBmp(Bitmap mTrunkBitmap) {        this.mTrunkBmp = mTrunkBitmap;    }    /**     * 设置刻度选中图片     */    public void setTrunkBmpDeep(Bitmap mTrunkBitmapDeep) {        this.mTrunkBmpDeep = mTrunkBitmapDeep;    }    /**     * isProfit=true(是止盈)     */    public void setIsProfit(boolean isProfit) {        this.isProfit = isProfit;    }    /**     * 根据止盈止损类型设置游标上的颜色值     */    public int getCursorTextColor() {        return isProfit ? COLOR_PROFIT_TEXT : COLOR_LOSS_TEXT;    }    /**     * 根据止盈止损类型设置刻度干上的颜色值     */    public int getTrunkTextColor() {        return isProfit ? COLOR_PROFIT_LINE : COLOR_LOSS_LINE;    }    /**     * X轴坐标终点     *     * @return     */    public double getXAxisEnd() {        return mXAxisEnd;    }    /**     * X轴坐标起点     *     * @return     */    public double getXAxisStart() {        return mXAxisStart;    }    /**     * 设置范围(最大值和最小值)     *     * @param mXAxisStart     * @param mXAxisEnd     */    public void setValueScale(double mXAxisStart, double mXAxisEnd) {        this.mXAxisStart = mXAxisStart;        this.mXAxisEnd = mXAxisEnd;    }    /**     * 设置游标位置(在屏幕位置).在初始化时调用     *     * @param x     */    public void setXValue(double x) {        if (mXAxisStart != 0 || mXAxisEnd != 1)            noSetX = false;        this.x = x;        this.scrollValue = String.valueOf(x);        this.value = x;    }    public void setOnScrollListener(OnScrollListener onScrollListener) {        this.onScrollListener = onScrollListener;    }    /**     * 根据x在屏幕的像素点坐标计算实际x值     *     * @return     */    private double getXValueForPx(double xpx) {        double d = (xpx - getPaddingLeft() - mCursorWidth / 2.0f) / mScaling + mXAxisStart;        return d;    }    private double getXForXvalue(double xvalue) {        int x = getPaddingLeft() + (int) ((xvalue - mXAxisStart) * mScaling + mCursorWidth / 2.0f + 0.5f);        return x;    }    /**     * 根据手机的分辨率从 dip 的单位 转成为 px(像素)     */    private int dip2px(Context context, float dpValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (dpValue * scale + 0.5f);    }    /**     * 将sp值转换为px值,保证文字大小不变     *     * @param spValue     * @return     */    private int sp2px(Context context, float spValue) {        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;        return (int) (spValue * fontScale + 0.5f);    }    /**     * 获取像素位置     *     * @return     */    public double getXLocation() {        Paint.Align align = Paint.Align.LEFT;        double px = getXForXvalue(x);        if (noSetX) {            px = align == Paint.Align.LEFT ? 0 : getWidth();        }        if (px <= getPaddingLeft() + mCursorWidth / 2.0f)            px = getPaddingLeft() + mCursorWidth / 2.0f;        if (px >= getWidth() - getPaddingRight() - mCursorWidth / 2.0f)            px = getWidth() - getPaddingRight() - mCursorWidth / 2.0f;        return px;    }    /**     * 设置像素位置     *     * @param x     */    public void setXLocation(double x) {        setXValue(getXValueForPx(x));    }    public float getTextSize() {        return mCursorTextSize;    }    /**     * 滑动接口     */    public interface OnScrollListener {        /**         * 返回游标上的字         *         * @param x         * @return         */        String onScroll(double x);    }    public void setOnClickListener(OnClickListener onClickListener) {        this.onClickListener = onClickListener;    }    public interface OnClickListener {        String onClick(double x);    }    private double getWidthForXValue() {        double strat = getXForXvalue(x);        return strat != 0 && strat > 0 ? strat : 1;    }    float startX = 0;    float startY = 0;    boolean isClick = true;    @SuppressLint("ClickableViewAccessibility")    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                getParent().requestDisallowInterceptTouchEvent(true);                if ((Math.abs(event.getX() - x) <= mCursorWidth) && (getXValueForPx(event.getX()) <= mXAxisEnd &&                        getXValueForPx(event.getX()) >= mXAxisStart)) {                    setXLocation(event.getX());                }                startX = event.getRawX();                startY = event.getRawY();                isClick = true;                break;            case MotionEvent.ACTION_MOVE:                float dx = event.getRawX() - startX;                float dy = event.getRawY() - startY;                if (onScrollListener != null) {                    setXLocation(event.getX());                    this.scrollValue = onScrollListener.onScroll(getXValueForPx(getXLocation()));                    this.value = getXValueForPx(getXLocation());                } else if (Math.abs(dx) > mTouchSlop || Math.abs(dy) > mTouchSlop) {                    isClick = false;                }                break;            case MotionEvent.ACTION_UP:                double tempX = getXForXvalue(getXLocation());                if (Math.abs(getXLocation() - tempX) <= mCursorWidth && (getXValueForPx(event.getX()) <= mXAxisEnd &&                        getXValueForPx(event.getX()) >= mXAxisStart)) {                    setXLocation(tempX);                } else if (isClick && event.getEventTime() - event.getDownTime() < mClickTimeout) {                    //作为点击事件操作                    if (onClickListener != null) {                        setXLocation(event.getX());                        this.scrollValue = onClickListener.onClick(getXValueForPx(getXLocation()));                        this.value = getXValueForPx(getXLocation());                    }                }                break;        }        invalidate();        return true;    }    /**     * 当前游标所在位置     *     * @return     */    public double getValue() {        return this.value;    }    /**     * 当前刻度干的最大值     *     * @return     */    public double getMaxValue() {        return this.mXAxisEnd;    }    /**     * 当前刻度干的最小值     *     * @return     */    public double getMinValue() {        return this.mXAxisStart;    }    /**     * 增加参数(根据传入的策略类型,来设置精度)(百分比2个精度,点差不需要,价格根据instrument中的精度值设置)     */    public void setPrecision(int precision) {        this.precision = (int) (Math.log(precision) / Math.log(10));    }    /**     * 增加参数(设置类型)     */    public void setType(Boolean isInteger) {        this.isInteger = isInteger;    }    /**     * 获取当前字符的宽度(设置位置)     */    private int computeMaxStringWidth(String strings) {        TextView textView = new TextView(getContext());        textView.setText(strings);        TextPaint paint = textView.getPaint();        int widthText = (int) Layout.getDesiredWidth(strings, 0,                strings.length(), paint);        return widthText;    }    /**     * 根据文字的宽度重新设置字体的大小(超过三个字符就缩小)     *     * @param text     * @param textWidth     */    private void refitText(String text, int textWidth) {        if (textWidth > 0) {            float[] widths = new float[text.length()];            Rect rect = new Rect();            mPaint.getTextBounds(text, 0, text.length(), rect);            int textWidths = rect.width();            mCursorTextSize = this.getTextSize();            while (textWidths > 48) {                mCursorTextSize = mCursorTextSize - 1;                mPaint.setTextSize(mCursorTextSize);                textWidths = mPaint.getTextWidths(text, widths);            }            mPaint.setTextSize(mCursorTextSize);        }        invalidate();    }}

使用示例:

package com.example.administrator.myapplication;import android.graphics.BitmapFactory;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.EditText;import android.widget.TextView;import java.text.NumberFormat;public class MainActivity extends AppCompatActivity {    private EditText content;    private EditText content1;    private CustomTakeValueArticle profitLimitScrollbar;    private CustomTakeValueArticle lossLimitScrollbar;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    private void initView() {        content = (EditText) findViewById(R.id.content);        content1 = (EditText) findViewById(R.id.content1);        profitLimitScrollbar = (CustomTakeValueArticle) findViewById(R.id.profit_limit_scrollbar);        lossLimitScrollbar = (CustomTakeValueArticle) findViewById(R.id.loss_limit_scrollbar);        initScrollbar();        setScrollBarValue();    }    /**     * 初始化Scrollbar相关配置参数     */    private void initScrollbar() {        profitLimitScrollbar.setCursorBmp(BitmapFactory.decodeResource(getResources(), R.mipmap.red_cursor));        profitLimitScrollbar.setTrunkBmp(BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_red));        profitLimitScrollbar.setTrunkBmpDeep(BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_red_deep));        profitLimitScrollbar.setIsProfit(true);        profitLimitScrollbar.setOnScrollListener(new CustomTakeValueArticle.OnScrollListener() {            @Override            public String onScroll(double x) {                changeScrollBarValue(x, content);                return String.valueOf(x);            }        });        profitLimitScrollbar.setOnClickListener(new CustomTakeValueArticle.OnClickListener() {            @Override            public String onClick(double x) {                changeScrollBarValue(x, content);                return String.valueOf(x);            }        });        lossLimitScrollbar.setCursorBmp(BitmapFactory.decodeResource(getResources(), R.mipmap.blue_cursor));        lossLimitScrollbar.setTrunkBmp(BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_blue));        lossLimitScrollbar.setTrunkBmpDeep(BitmapFactory.decodeResource(getResources(), R.mipmap.cursor_line_blue_deep));        lossLimitScrollbar.setIsProfit(false);        lossLimitScrollbar.setOnScrollListener(new CustomTakeValueArticle.OnScrollListener() {            @Override            public String onScroll(double x) {                changeScrollBarValue(x, content1);                return String.valueOf(x);            }        });        lossLimitScrollbar.setOnClickListener(new CustomTakeValueArticle.OnClickListener() {            @Override            public String onClick(double x) {                changeScrollBarValue(x, content1);                return String.valueOf(x);            }        });    }    /**     * 点击和滑动更新实时值     *     * @param x     * @param limitValue     */    private void changeScrollBarValue(double x, TextView limitValue) {        NumberFormat capitalNumberFormat;        capitalNumberFormat = NumberFormat.getInstance();        capitalNumberFormat.setMaximumFractionDigits(2);        capitalNumberFormat.setMinimumFractionDigits(2);        capitalNumberFormat.setGroupingUsed(false);        NumberFormat mNumberFormat;        mNumberFormat = NumberFormat.getInstance();        mNumberFormat.setMaximumFractionDigits(0);        mNumberFormat.setMinimumFractionDigits(0);        mNumberFormat.setGroupingUsed(false);        if (limitValue == content) {            limitValue.setText(capitalNumberFormat.format(x));        } else {            limitValue.setText(mNumberFormat.format(x));        }    }    /**     * 设置ScrollBar相关数据参数     */    private void setScrollBarValue() {        profitLimitScrollbar.invalidate();        lossLimitScrollbar.invalidate();        profitLimitScrollbar.setType(false);        lossLimitScrollbar.setType(true);        profitLimitScrollbar.setPrecision(2);        profitLimitScrollbar.setXValue(50.02);        content.setText("50.02");        lossLimitScrollbar.setXValue(40);        content1.setText("40");        profitLimitScrollbar.setValueScale(0,                120);        lossLimitScrollbar.setValueScale(0,                100);    }}

相关实现参数可根据需求在代码中修改!

效果图:
这里写图片描述

源码下载

3 0