美文网首页
Android 柱状图 给柱状图添加指示器

Android 柱状图 给柱状图添加指示器

作者: 小熊_c37d | 来源:发表于2017-07-25 11:16 被阅读0次
    QQ视频20170725110114.gif

    绘制柱状我就不多说了,自行查看如何绘制

    我们来看看下面的指示器 是如何绘制的 首先我们来看看跟之前的onDraw 有什么区别

    mIndexMoveMeasure 计算了 指示器于柱状图 移动的差距比例 DrawIndex 绘制指示器

    Paste_Image.png
    DrawIndex 我们来看看里面做了什么
    • 首先这里绘制了 指示器上的三角形 moveX 计算指示器要移动的距离 通过刚才计算的 比例来计算


      Paste_Image.png
    • 绘制指示器文本框 限制右边距

    Paste_Image.png
    • 判断指示器 当前处于的位置 判断 topX 也就是三角形的 上边的x坐标 是不是 矩阵范围内, 不过这个时候有个问题空白区域的时候 就找不到因此 做一个处理 找不到时 绘制上一次绘制的文本
    Paste_Image.png
    完整代码

    <code>

    package com.app.framework.widget.chart.rect;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.LinearGradient;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.Point;
    import android.graphics.Rect;
    import android.graphics.Shader;
    import android.support.annotation.Nullable;
    import android.text.method.NumberKeyListener;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    
    import java.util.ArrayList;
    import java.util.List;
    
    
    public class SlideRectChart extends AbsChart {
        private static final String TAG = "SlideRectChart";
    
        /**
         * 柱子的画笔
         */
        private Paint mSlideRectPaint;
        /**绘制时间画笔*/
        private  Paint mTimePaint;
    
        /**指示器画笔*/
        private Paint mIndexPaint;
        /**指示器文本画笔*/
        private Paint mIndexTxtPaint;
        /**
         * 柱子的大小
         */
        private float mRectSize;
    
        /**move手指移动与 指针移动的比例*/
        private float mIndexMoveMeasure;
    
        /**
         * 柱子之间的边距
         */
        private float mRectLeft;
    
        /**
         * 右边超出的范围
         */
        private float mRectDrawWidth;
    
        public ArrayList<TimeData> mTimeData;
    
        /**判断单位*/
        private SlideRectEnum tag =SlideRectEnum.hour;
    
        private List<Rect> mRectList;
        private LinearGradient mLinearGradient;
    
        public  enum  SlideRectEnum{
            day,
            month,
            year,
            hour,
    
        }
        public SlideRectChart(Context context) {
            super(context);
            init();
        }
    
        public SlideRectChart(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        private void init() {
            if (mSlideRectPaint == null) {
                mSlideRectPaint = new Paint();
            }
            mSlideRectPaint.setAntiAlias(true);
            mSlideRectPaint.setStyle(Paint.Style.FILL);
            mSlideRectPaint.setColor(Color.GREEN);
            if(mTimePaint==null){
                mTimePaint=new Paint();
            }
            mTimePaint.setAntiAlias(true);
            mTimePaint.setStyle(Paint.Style.STROKE);
            mTimePaint.setColor(Color.BLACK);
            mTimePaint.setTextSize(dip2px(12));
            mTimePaint.setTextAlign(Paint.Align.LEFT);
    
    
            if(mIndexPaint==null){
                mIndexPaint=new Paint();
            }
            mIndexPaint.setAntiAlias(true);
            mIndexPaint.setStyle(Paint.Style.FILL);
            mIndexPaint.setColor(Color.BLUE);
    
            if(mIndexTxtPaint==null){
                mIndexTxtPaint=new Paint();
            }
            mIndexTxtPaint.setAntiAlias(true);
            mIndexTxtPaint.setStyle(Paint.Style.FILL);
            mIndexTxtPaint.setColor(Color.WHITE);
            mIndexTxtPaint.setTextSize(dip2px(12));
            mIndexTxtPaint.setTextAlign(Paint.Align.CENTER);
    
    
            getBrokenLinePaint().setTextSize(dip2px(12));
            getBrokenLinePaint().setStrokeWidth(dip2px(0.5f));
            getBrokenLinePaint().setStyle(Paint.Style.FILL);
        }
    
        @Override
        public void setValue(float[] value) {
            super.setValue(value);
            this.mSlideX=0;
        }
        public  void  setTimeData(ArrayList<TimeData> timeData){
            this.mTimeData =timeData;
        }
        public  void  setTag(SlideRectEnum slideRectEnum){
            this.tag=slideRectEnum;
        }
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            mRectSize = getViewWidth() / 24;
            mRectLeft = dip2px(4);
            mRectList=new ArrayList<>();
            mLinearGradient = new LinearGradient(getBrokenLineLeft()-1 ,getBrokenLineTop(),getBrokenLineLeft(),getBrokenLineTop(),new int[]{0x00ffffff,Color.BLUE}, null, Shader.TileMode.CLAMP);
            getBrokenLinePaint().setShader(mLinearGradient);
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
            onTouchEvent(event);
            return true;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            /**计算最多移动的距离*/
            mRectDrawWidth = ((mRectLeft * mPoints.length) + (mRectSize * mPoints.length + getBrokenLineLeft() - getViewWidth()));
    
            mIndexMoveMeasure=getNeedDrawWidth()/mRectDrawWidth;
            DrawRect(canvas);
    
            DrawIndex(canvas);
        }
        private String oldText="";
        /**绘制指示器*/
        private void DrawIndex(Canvas canvas) {
            float moveX=mSlideX*mIndexMoveMeasure;
            float leftX=getBrokenLineLeft()+moveX;
            float rightX=getBrokenLineLeft()+mRectSize+moveX;
            float topX =rightX-(rightX-leftX)/2;
            float topY=getNeedDrawHeight()+getBrokenLineTop()+2;
            float bottomY=getNeedDrawHeight()+getBrokenLineTop()+mRectSize/2;
    
            if(leftX>=getViewWidth()-mRectSize-mRectLeft){
                leftX=getViewWidth()-mRectSize-mRectLeft;
                rightX=getViewWidth()-mRectLeft;
                topX=rightX-(rightX-leftX)/2;
            }
    
            Path mPath=new Path();
            mPath.moveTo(leftX,bottomY);
            mPath.lineTo(topX,topY);
            mPath.lineTo(rightX,bottomY);
            mPath.lineTo(leftX,bottomY);
            canvas.drawPath(mPath,mIndexPaint);
    
            /**绘制指示器举证*/
            Rect belowRect=new Rect();
            int  left= (int) (leftX-getBrokenLineLeft());
            int  right = (int) (leftX+getBrokenLineLeft());
            int  top= (int) (topY+getBrokenLineTop()/1.5);
            int  bottom=getViewHeight();
            if(right>=getViewWidth()-mRectLeft){
                left= (int) (getViewWidth()-mRectLeft-getBrokenLineLeft()*2);
                right= (int) (getViewWidth()-mRectLeft);
            }
            belowRect.left=left;
            belowRect.right=right;
            belowRect.top=top;
            belowRect.bottom=bottom;
            canvas.drawRect(belowRect,mIndexPaint);
    
            int  bx=belowRect.left+(belowRect.right-belowRect.left)/2;
    
    
            for (int i = 0; i < mRectList.size(); i++) {
                Rect rect=mRectList.get(i);
                if(rect.left<=topX && rect.right>=topX ){
    
                    if(tag==SlideRectEnum.hour) {
                        oldText=mTimeData.get(i).getHour() + ":00" + " γ: " + floatKeepTwoDecimalPlaces(getValue()[i]);
                        canvas.drawText(oldText, bx, getHeight() - dip2px(2), mIndexTxtPaint);
                    }
                    if(tag==SlideRectEnum.day) {
                        oldText=mTimeData.get(i).getDay() + "日" + " γ: " + floatKeepTwoDecimalPlaces(getValue()[i]);
                        canvas.drawText(oldText, bx, getHeight() - dip2px(2), mIndexTxtPaint);
                    }
                    break;
                }
                if(mRectList.size()==i+1){
                    canvas.drawText(oldText, bx, getHeight() - dip2px(2), mIndexTxtPaint);
                }
            }
    
    
    
    
        }
    
    
        /**绘制矩阵*/
        private void DrawRect(Canvas canvas) {
            mRectList.clear();
            for (int i = 0; i < mPoints.length; i++) {
                Point point = mPoints[i];
                Rect rect = new Rect();
                int left = (int) ((mRectLeft * i) + (mRectSize * i + getBrokenLineLeft()) - mSlideX);
                int right = ((int) ((mRectLeft * i) + (mRectSize * i + mRectSize + getBrokenLineLeft() - mSlideX)));
    
                if(tag==SlideRectEnum.hour){
                    if(mTimeData!=null){
                        TimeData timeData=mTimeData.get(i);
                        if(i==0 || timeData.getHour()==1){
                            canvas.drawLine(left,getNeedDrawHeight()+getBrokenLineTop(),left,0,getBrokenLinePaint());
                            canvas.drawText(timeData.getDay()+"日",left+2,getBrokenLineTop(),getBrokenLinePaint());
                        }
                    }
                }
                if(tag==SlideRectEnum.day){
                    if(mTimeData!=null){
                        TimeData timeData=mTimeData.get(i);
                        if(i==0 || timeData.getDay()==1){
                            canvas.drawLine(left,getNeedDrawHeight()+getBrokenLineTop(),left,0,getBrokenLinePaint());
                            canvas.drawText(timeData.getMonth()+"月",left+2,getBrokenLineTop(),getBrokenLinePaint());
                        }
                    }
                }
    
    
                /**限制柱状绘制范围*/
                if (left < getBrokenLineLeft()) {
                    left = (int) getBrokenLineLeft();
                }
                if (right < getBrokenLineLeft()) {
                    right = (int) getBrokenLineLeft();
                }
                rect.left = left;
                rect.right = right;
                rect.bottom = (int) (getNeedDrawHeight() + getBrokenLineTop());
                rect.top = point.y;
    
                mRectList.add(rect);
    
                canvas.drawRect(rect, mSlideRectPaint);
    
    
    
            }
        }
    
        private float mSlideX = 0;
        private float mLastDownX;
    
    
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
    
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mLastDownX = event.getX();
                    return  true;
                case MotionEvent.ACTION_UP:
                    mSlideX += (mLastDownX - event.getX());
                    mLastDownX = event.getX();
    
                    if (mSlideX <= 0) {
                        mSlideX = 0;
                    }
                    if (mSlideX >= mRectDrawWidth) {
                        mSlideX = mRectDrawWidth;
                    }
                    postInvalidate();
                    return true;
    
                case MotionEvent.ACTION_MOVE:
                    mSlideX += (mLastDownX - event.getX());
                    mLastDownX = event.getX();
                    if (mSlideX <= 0) {
                        mSlideX = 0;
                    }
                    if (mSlideX >= mRectDrawWidth) {
                        mSlideX = mRectDrawWidth;
                    }
                    postInvalidate();
                    return true;
    
            }
            return true;
    
        }
    }
    

    </code >

    相关文章

      网友评论

          本文标题:Android 柱状图 给柱状图添加指示器

          本文链接:https://www.haomeiwen.com/subject/nilwkxtx.html