Android绘制学习——基础形状

来源:互联网 发布:移动网络ip地址是什么 编辑:程序博客网 时间:2024/06/05 05:58

有些地方待优化处理,这里就没做处理,只是用来学习记录

public class BarChartView extends View {    private Context context;    // 画布的位置    private int XPoint;    private int YPoint;    //刻度长度    private int XScale = 100;    private int YScale = 60;    // xy轴的线长    private int XLength;    private int YLength;  // 要减去箭头的长度    // 顶部 底部文字的高度    private int topTextHight = 60;    private int bottomTextHight = 100;    // 设置柱状的高度    private int height = (int)dipToPx(20);    private float betweenHeight;    // 选中的id    private int chooseId = -1;    private int MaxDataSize = XLength / XScale;    private int[] mColors; //对象的颜色    private List<String> text = new ArrayList<>();  // 底部标题    private List<RunStatusBean> infos = new ArrayList<>();  // 每个横条的信息    // 初始化画笔    private Paint paint;    private Paint YPaint;    private Paint YArrowsPaint;    private Paint headPaint;    private Paint dottedPaint;    private Paint datePaint;    private Paint rectanglePaint;    private Paint textInRectangle;    private Paint bottomLinePaint;    private Paint bottomDiscripPain;    public BarChartView(Context context, AttributeSet attrs) {        super(context, attrs);        this.context = context;        // 初始化每一个级别的颜色         mColors = new int[]{Color.parseColor("#F47564"),Color.parseColor("#F2AE6D"),Color.parseColor("#4FC3B8") ,Color.parseColor("#64AFF4")};        // 初始化画笔        paint = new Paint();        paint.setStyle(Paint.Style.STROKE);        paint.setAntiAlias(true);        paint.setColor(Color.BLUE);        // y        YPaint = new Paint();        YPaint.setStyle(Paint.Style.STROKE);        YPaint.setAntiAlias(true);        YPaint.setColor(Color.parseColor("#B0B0B0"));        // y轴箭头arrows        YArrowsPaint = new Paint();        YArrowsPaint.setStyle(Paint.Style.STROKE);        YArrowsPaint.setAntiAlias(true);        YArrowsPaint.setColor(Color.parseColor("#B0B0B0"));        // 头部标题        headPaint = new Paint();        headPaint.setTextSize(dipToPx(15));        headPaint.setColor(Color.parseColor("#B0B0B0"));        headPaint.setAntiAlias(true);        headPaint.setTextAlign(Paint.Align.CENTER);        //虚线        dottedPaint = new Paint();        dottedPaint.setStyle(Paint.Style.STROKE);        PathEffect effects = new DashPathEffect(new float[]{5,5,5,5},1);        dottedPaint.setAntiAlias(true);        dottedPaint.setPathEffect(effects);        //日期文字        datePaint = new Paint();        datePaint.setAntiAlias(true);        datePaint.setTextSize(20);        datePaint.setTextAlign(Paint.Align.CENTER);        //矩形        rectanglePaint = new Paint();        rectanglePaint.setAntiAlias(true);        rectanglePaint.setStyle(Paint.Style.FILL);//充满        // 矩形中的文字        textInRectangle = new Paint();        textInRectangle.setTextSize(20);        textInRectangle.setColor(Color.parseColor("#FFFFFF"));        textInRectangle.setAntiAlias(true);        textInRectangle.setTextAlign(Paint.Align.CENTER);        //底部描述文字的矩形        bottomLinePaint = new Paint();        bottomLinePaint.setStyle(Paint.Style.STROKE);        bottomLinePaint.setStrokeWidth(16);        bottomLinePaint.setAntiAlias(true);        // 底部的描述文字        bottomDiscripPain = new Paint();        bottomDiscripPain.setColor(Color.parseColor("#A1A6BB"));        bottomDiscripPain.setAntiAlias(true);        bottomDiscripPain.setTextSize(26);        bottomDiscripPain.setTextAlign(Paint.Align.CENTER);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));    }    private int measureHeight(int measureSpec) {        int result = Constant.windowHeight / 3; //结果        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        switch (specMode) {            case MeasureSpec.AT_MOST:  // 子容器可以是声明大小内的任意大小                result = specSize;                break;            case MeasureSpec.EXACTLY:  //父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间.  比如EditTextView中的DrawLeft                result = (int)(Constant.windowHeight*(0.4));                break;            case MeasureSpec.UNSPECIFIED:  //父容器对于子容器没有任何限制,子容器想要多大就多大. 所以完全取决于子view的大小                result = specSize;                break;        }        return result;    }    private int measureWidth(int measureSpec) {        int result = Constant.windowWidth; //默认的size        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        switch (specMode) {            case MeasureSpec.AT_MOST:  // 子容器可以是声明大小内的任意大小                result = specSize;                break;            case MeasureSpec.EXACTLY:  //父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间.  比如EditTextView中的DrawLeft                result = specSize;                break;            case MeasureSpec.UNSPECIFIED:  //父容器对于子容器没有任何限制,子容器想要多大就多大. 所以完全取决于子view的大小                result = (text.size() + 2) * XScale;                break;            default:                break;        }        return result;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //画布宽高的确定        int measuredHeight = getMeasuredHeight();        int measuredWidth = getMeasuredWidth();        //起画点        YPoint = measuredHeight;        XPoint = 60;        // landy坐标        landY = YPoint - 16;        // y坐标长度        YLength = measuredHeight - bottomTextHight - topTextHight;        XLength = measuredWidth;        // y坐标刻度        YScale = YLength / 5;        MaxDataSize = XLength / XScale;        // 设置柱状的间距        betweenHeight = context.getResources().getDimensionPixelSize(R.dimen.y60);        /*-----------------------------------------------绘制图型--------------------------------------------*/        //Y        canvas.drawLine(XPoint, YPoint - bottomTextHight, XPoint, YPoint - YLength - bottomTextHight, YPaint);        //Y轴箭头        canvas.drawLine(XPoint, YPoint - YLength - bottomTextHight, XPoint - 3, YPoint-YLength - bottomTextHight + 6, YPaint);        canvas.drawLine(XPoint, YPoint - YLength - bottomTextHight, XPoint + 3, YPoint-YLength - bottomTextHight + 6, YPaint);        //X        canvas.drawLine(XPoint, YPoint - bottomTextHight, XPoint + text.size() * XScale, YPoint - bottomTextHight, YPaint);        // 头标题        canvas.drawText("单位:kwh",XPoint + dipToPx(30), topTextHight - 20, headPaint);        //x轴上的虚线        if(text.size() > 1){            for(int i=0; i<text.size(); i++){                if (i == chooseId){                    dottedPaint.setColor(Color.parseColor("#222328"));                }else{                    dottedPaint.setColor(Color.parseColor("#B0B0B0"));                }                Path path = new Path();                path.moveTo(XPoint + (i+1) * XScale, YPoint - bottomTextHight);                path.lineTo(XPoint + (i + 1) * XScale, YPoint - YLength - bottomTextHight);                canvas.drawPath(path, dottedPaint);            }        }        // x轴下的文字        if(text.size() > 1){            for(int i=0; i<text.size(); i++){                if (i == chooseId){                    datePaint.setColor(Color.parseColor("#0786E7"));                }else{                    datePaint.setColor(Color.parseColor("#B0B0B0"));                }                canvas.drawText(text.get(i),XPoint + (i+1) * XScale,YPoint -bottomTextHight + 40,datePaint);            }        }        // 画矩形(主要计算出矩形的长度)        for (int i =0; i<infos.size(); i++){            int heightCount = 0;            // 颜色控制            if (infos.get(i).getStatus() == 0){ // 关机                rectanglePaint.setColor(mColors[0]);                heightCount = 1;            }if (infos.get(i).getStatus() == 10){// 正常                rectanglePaint.setColor(mColors[1]);                heightCount = 2;            }if (infos.get(i).getStatus() == 20){// 故障                heightCount = 3;                rectanglePaint.setColor(mColors[2]);            }if (infos.get(i).getStatus() == 30){// 带病运行                heightCount = 4;                rectanglePaint.setColor(mColors[3]);            }            // 画矩形            float left  = ((infos.get(i).getStart()-1) + 0.5f) * XScale + XPoint;   // 拿到月份确定left的位置 和 rigth的位置()            float right  = left + (infos.get(i).getEnd()-infos.get(i).getStart() + 1)*XScale;            float top  = YPoint - bottomTextHight - heightCount * (betweenHeight) - height ;   // 根据状态判断高度            float bottom  = YPoint - bottomTextHight - heightCount * (betweenHeight)  ;   // height 为矩形的高度            RectF oval3 = new RectF(left, top, right, bottom);// 设置个新的长方形            canvas.drawRoundRect(oval3, 10, 10, rectanglePaint);//第二个参数是x半径,第三个参数是y半径            // 画文字            canvas.drawText(infos.get(i).getDesc(), (right - left) / 2 + left, height / 2 + top + 6, textInRectangle);        }        //画底部描述线条        bottomLinePaint.setColor(mColors[3]);        canvas.drawLine(XPoint, landY, XPoint + landWidth, landY, bottomLinePaint);        bottomLinePaint.setColor(mColors[2]);        canvas.drawLine(XPoint + landWidth + landAmong + textWidth(landText[0],26,bottomLinePaint), landY                , XPoint + (landWidth *2) + landAmong + textWidth(landText[0],26,bottomLinePaint), landY, bottomLinePaint);        bottomLinePaint.setColor(mColors[1]);        canvas.drawLine(XPoint + (landWidth *2) + (landAmong *2) + textWidth(landText[0],26,bottomLinePaint)+textWidth(landText[1],26,bottomLinePaint)                , landY, XPoint + (landWidth *3) + (landAmong *2)+ textWidth(landText[0],26,bottomLinePaint)+textWidth(landText[1],26,bottomLinePaint), landY, bottomLinePaint);        bottomLinePaint.setColor(mColors[0]);        canvas.drawLine(XPoint + (landWidth *3) + (landAmong *3)+ 2*textWidth(landText[0],26,bottomLinePaint)+textWidth(landText[1],26,bottomLinePaint)                , landY, XPoint + (landWidth *4) + (landAmong *3)+2*textWidth(landText[0],26,bottomLinePaint)+textWidth(landText[1],26,bottomLinePaint)                , landY, bottomLinePaint);        //画底部描述文字        canvas.drawText(landText[0]                , excursion + XPoint + landWidth + (landAmong + textWidth(landText[0],26,bottomDiscripPain))/ 2                , landY + 8, bottomDiscripPain);        canvas.drawText(landText[1]                , excursion + XPoint + (landWidth * 2) + (landAmong + textWidth(landText[1],26,bottomDiscripPain))/ 2 + (landAmong + textWidth(landText[0],26,bottomDiscripPain))                ,landY + 8, bottomDiscripPain);        canvas.drawText(landText[2]                , excursion + XPoint + (landWidth * 3) +(landAmong + textWidth(landText[0],26,bottomDiscripPain))+(landAmong + textWidth(landText[1],26,bottomDiscripPain))+((landAmong + textWidth(landText[2],26,bottomDiscripPain))/2)                ,landY +8,bottomDiscripPain);        canvas.drawText(landText[3]                ,excursion + XPoint + (landWidth * 4) +(landAmong + textWidth(landText[0],26,bottomDiscripPain))+(landAmong + textWidth(landText[1],26,bottomDiscripPain))+(landAmong + textWidth(landText[2],26,bottomDiscripPain))+((landAmong + textWidth(landText[3],26,bottomDiscripPain))/2)                ,landY +8,bottomDiscripPain);    }    private int landWidth = 60;    private int landAmong = 60;    private int excursion = -14;  // land文字向x方向的偏移量    private float landY;    private String [] landText = {"正常","带病运行","故障","关机"};    private float dipToPx(float dip) {        float density = getContext().getResources().getDisplayMetrics().density;        return (int)(dip * density + 0.5f * (dip >= 0 ? 1 : -1));    }    public void setHeight(int height) {    // 设置柱状高度        this.height = height;    }    public void setText(List<String> text) {   // 设置底部标题        this.text = text;        this.invalidate();    }    public void setInfos(List<RunStatusBean> infos) {   // 设置info        this.infos = infos;        this.invalidate();    }    private float textWidth(String string, int size, Paint paint){        paint.setTextSize(size);        float textWidth =paint.measureText(string + "");        return textWidth;    }}

原创粉丝点击