美文网首页
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