抄来的 横向选择器

2019-06-12  本文已影响0人  细雨么么

原 吉他gay boy 地址:https://github.com/ZBJDSBJ/ScaleRuler

原博客地址:https://blog.csdn.net/zbjdsbj/article/details/51180011

侵删



package com.vortex.rxtest;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.RectF;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.VelocityTracker;

import android.view.View;

import android.view.ViewConfiguration;

import android.widget.Scroller;

import java.util.ArrayList;

/**

* Created by zoubo on 16/2/26.

* 小数点横向滚动刻度尺

*/

public class DecimalScaleRulerViewextends View {

private ArrayListtimeData =new ArrayList<>();

    private int mMinVelocity;  //最小滑动距离

    private ScrollermScroller;

    private VelocityTrackermVelocityTracker;

    private int mWidth;  //view 宽度

    private int mHeight;

    private float mValue =10;

    private float mMaxValue =24;

    private float mMinValue =0;

    private int perNumber =12; //两个值之间的 精确度格子

    private int mItemSpacing =5;  //item 间距

    private int mPerSpanValue =5;  //每隔的值

    private int bigPerSpanValue =perNumber *mPerSpanValue; //一大格的值

    private int mMaxLineHeight =40;

    private int mMiddleLineHeight =35;

    private int mMinLineHeight =35;

    private int mLineWidth;

    private int mTextMarginTop =5;

    private float mTextHeight;

    private PaintmTextPaint; // 绘制文本的画笔

    private PaintmLinePaint;

    private PaintbgPaint;

    private int mTotalLine;  //共有这么多条线

    private int mMaxOffset;  //最大偏移量

    private float mOffset; // 默认尺起始点在屏幕中心, offset是指尺起始点的偏移值  当前偏移量

    private int mLastX, mMove;

    private OnValueChangeListenermListener;

    public DecimalScaleRulerView(Context context) {

this(context, null);

        init(context);

    }

public DecimalScaleRulerView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

        init(context);

    }

public DecimalScaleRulerView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

        init(context);

    }

protected void init(Context context) {

mScroller =new Scroller(context);

        mMinVelocity = ViewConfiguration.get(getContext()).getScaledMinimumFlingVelocity();

        mItemSpacing = DrawUtil.dip2px(14);

        mLineWidth = DrawUtil.dip2px(1);

        mTextMarginTop = DrawUtil.dip2px(11);

        mTextPaint =new Paint(Paint.ANTI_ALIAS_FLAG);

        mTextPaint.setTextSize(DrawUtil.sp2px(16));

        mTextPaint.setColor(0X80222222);

        mTextHeight = TextUtil.getFontHeight(mTextPaint);

        bgPaint =new Paint();

        bgPaint.setStyle(Paint.Style.FILL);

        bgPaint.setAntiAlias(true);

        bgPaint.setAlpha(200);

        bgPaint.setColor(Color.BLUE);

        mLinePaint =new Paint(Paint.ANTI_ALIAS_FLAG);

        mLinePaint.setStrokeWidth(mLineWidth);

        mLinePaint.setColor(0X80222222);

        mTotalLine = (int) (mMaxValue *bigPerSpanValue -mMinValue *bigPerSpanValue) /mPerSpanValue +1;

        mMaxOffset = -(mTotalLine -1) *mItemSpacing;

        mOffset = (mMinValue -mValue) *perNumber *mItemSpacing;

    }

public void setParam(int itemSpacing, int maxLineHeight, int middleLineHeight, int minLineHeight, int textMarginTop, int textSize) {

mItemSpacing = itemSpacing;

        mMaxLineHeight = maxLineHeight;

        mMiddleLineHeight = middleLineHeight;

        mMinLineHeight = minLineHeight;

        mTextMarginTop = textMarginTop;

        mTextPaint.setTextSize(textSize);

    }

public void initViewParam(float defaultValue, float minValue, float maxValue, int spanValue) {

this.mValue = defaultValue;

        this.mMaxValue = maxValue;

        this.mMinValue = minValue;

        this.mPerSpanValue = spanValue;

        this.mTotalLine = (int) (maxValue *10 - minValue *10) / spanValue +1;

        mMaxOffset = -(mTotalLine -1) *mItemSpacing;

        mOffset = (minValue - defaultValue) / spanValue *mItemSpacing *10;

        invalidate();

        setVisibility(VISIBLE);

    }

/**

    * 设置用于接收结果的监听器

    *

    * @param listener

    */

    public void setValueChangeListener(OnValueChangeListener listener) {

mListener = listener;

    }

@Override

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

        if (w >0 && h >0) {

mWidth = w;

            mHeight = h;

        }

}

public void setTimeData(ArrayList sData) {

timeData.clear();

        timeData.addAll(sData);

        postInvalidate();

    }

private void DrawBg(Canvas mcanvas,int srcPointX,float mOffset) {

for (TimeModeltimeModel :timeData) {

int start =timeModel.startTime;

            int end =timeModel.endTime;

            float sPercent = (start / (mMaxValue *bigPerSpanValue)) * Math.abs(mMaxOffset)+srcPointX+mOffset;

            float ePercent = (end / (mMaxValue *bigPerSpanValue)) * Math.abs(mMaxOffset)+srcPointX+mOffset;

            RectFrect =new RectF(sPercent, 0, ePercent, mHeight-100);

            mcanvas.drawRect(rect, bgPaint);

        }

}

@Override

    protected void onDraw(Canvas canvas) {

//        super.onDraw(canvas);

        float left, height;

        Stringvalue;

        int alpha;

        float scale;

        /**

        * 相当于起始点右移了半个屏幕

        */

        int srcPointX =mWidth /2; // 默认表尺起始点在屏幕中心

        DrawBg(canvas,srcPointX,mOffset);

        for (int i =0; i

/**

            * 这里相当于移动的不是view 而是坐标原点

            * srcPointX是因为在中间,相当于右移正的半个屏幕,然后 移动的距离  mOffset 就是坐标点,从这里

            * 开始画整个view

*/

            left =srcPointX +mOffset +i *mItemSpacing;

            if (left <0 ||left >mWidth) {

continue;

            }

if (i %perNumber ==0) {

height =mHeight -mMinLineHeight;

                mLinePaint.setColor(Color.BLUE);

            }else if (i % (perNumber /2) ==0) {

height =mHeight -mMiddleLineHeight;

                mLinePaint.setColor(Color.GREEN);

            }else {

mLinePaint.setColor(Color.GRAY);

                height =mHeight -mMaxLineHeight;

            }

//            scale = 1 - Math.abs(left - srcPointX) / srcPointX;

//            alpha = (int) (255 * scale * scale);

//            mLinePaint.setAlpha(alpha);

            canvas.drawLine(left, 0, left, height, mLinePaint);

            if (i %perNumber ==0) {// 大指标,要标注文字

                value = String.valueOf((int) (mMinValue +i /perNumber));

//                mTextPaint.setAlpha(alpha);

                canvas.drawText(value, left -mTextPaint.measureText(value) /2,

                        height +mTextMarginTop +mTextHeight - DrawUtil.dip2px(3), mTextPaint);

            }

}

}

@Override

    public boolean onTouchEvent(MotionEvent event) {

int action = event.getAction();

        int xPosition = (int) event.getX();

        if (mVelocityTracker ==null) {

mVelocityTracker = VelocityTracker.obtain();

        }

mVelocityTracker.addMovement(event);

        switch (action) {

case MotionEvent.ACTION_DOWN:

mScroller.forceFinished(true);

                mLastX =xPosition;

                mMove =0;

break;

            case MotionEvent.ACTION_MOVE:

mMove = (mLastX -xPosition);

                changeMoveAndValue();

break;

            case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

countMoveEnd();

                countVelocityTracker();

return false;

            // break;

            default:

break;

        }

mLastX =xPosition;

return true;

    }

private void countVelocityTracker() {

mVelocityTracker.computeCurrentVelocity(1000);

        float xVelocity =mVelocityTracker.getXVelocity();

        if (Math.abs(xVelocity) >mMinVelocity) {

mScroller.fling(0, 0, (int)xVelocity, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0);

        }

}

/**

    * mOffset是个负值

    */

    private void countMoveEnd() {

mOffset -=mMove;

        if (mOffset <=mMaxOffset) {

mOffset =mMaxOffset;

        }else if (mOffset >=0) {

mOffset =0;

        }

mLastX =0;

        mMove =0;

        mValue =mMinValue *bigPerSpanValue + Math.round(Math.abs(mOffset) *1.0f /mItemSpacing) *mPerSpanValue;

        mOffset = (mMinValue *bigPerSpanValue -mValue) /mPerSpanValue *mItemSpacing; // 矫正位置,保证不会停留在两个相邻刻度之间

        notifyValueChange();

        postInvalidate();

    }

private void changeMoveAndValue() {

mOffset -=mMove;

        if (mOffset <=mMaxOffset) {

mOffset =mMaxOffset;

            mMove =0;

            mScroller.forceFinished(true);

        }else if (mOffset >=0) {

mOffset =0;

            mMove =0;

            mScroller.forceFinished(true);

        }

mValue =mMinValue *bigPerSpanValue + Math.round(Math.abs(mOffset) *1.0f /mItemSpacing) *mPerSpanValue;

        notifyValueChange();

        postInvalidate();

    }

private void notifyValueChange() {

if (null !=mListener) {

mListener.onValueChange(mValue);

        }

}

public interface OnValueChangeListener {

void onValueChange(float value);

    }

@Override

    public void computeScroll() {

super.computeScroll();

        if (mScroller.computeScrollOffset()) {

if (mScroller.getCurrX() ==mScroller.getFinalX()) {// over

                countMoveEnd();

            }else {

int xPosition =mScroller.getCurrX();

                mMove = (mLastX -xPosition);

                changeMoveAndValue();

                mLastX =xPosition;

            }

}

}

}

上一篇 下一篇

猜你喜欢

热点阅读