Android自定义View(三)柱状图

原创 2016年08月31日 13:32:24

        杂七杂八,自己完成了一个自定义柱状图的实现。因为有前面画过一个手表的些微经验,这次开始的过程还是挺顺利的,后期遇到的最大问题就是画布旋转后找位置这个过程,简直要命。而且前一篇正好巧妙的规避了这个问题所以没注意到。

        主要用了两个类,一个数据模型类和一个自定义View的类。

        先放效果图,然后直接上代码。

        竖屏:


        横屏:

        数据模型类:

public class CharData {
    private String name;//名称
    private float number;//数值
    private int color;//颜色

    public CharData(String name, float number, int color) {
        this.name = name;
        this.number = number;
        this.color = color;
    }

    public CharData() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public float getNumber() {
        return number;
    }

    public void setNumber(float number) {
        this.number = number;
    }

    public int getColor() {
        return color;
    }

    public void setColor(int color) {
        this.color = color;
    }
}

        自定义属性的xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="BarGraphView">
        <attr name="title" format="string" />
        <attr name="titleSize" format="dimension" />
        <attr name="titleColor" format="color" />
        <attr name="maxLimit" format="integer" />
        <attr name="unit" format="string" />
    </declare-styleable>

</resources>

        状态图实现代码:

public class BarGraphView extends View {

    private int clickPos = -1;

    private final String TAG = BarGraphView.class.getName();
    private final int[] colors = {0xffCCFFFF,0xff99CCFF,0xffFF9900,0xff99FFFF,0xffCC99FF};//默认颜色池
    private final int whiteBg = 0xffffffff;
    private final int lGrayBg = 0xfff6f6f6;
    private Paint mPaint;//画笔
    //标题三件套
    private String title;
    private int titleColor;
    private float titleSize;
    //数据源
    private List<CharData> datas;
    private int width;//控件宽
    private int height;//控件高
    private int maxLimit;//数据最大值
    private String unit;//数据最大值
    public BarGraphView(Context context) {
        this(context,null);
    }
    public BarGraphView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }
    public BarGraphView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BarGraphView,defStyleAttr,0);
        int count = typedArray.getIndexCount();
        for (int i=0; i<count; i++){
            int attr = typedArray.getIndex(i);
            switch (attr){
                case R.styleable.BarGraphView_title:
                    title = typedArray.getString(attr);
                    break;
                case R.styleable.BarGraphView_titleColor:
                    titleColor = typedArray.getColor(attr, Color.BLACK);
                    break;
                case R.styleable.BarGraphView_titleSize:
                    titleSize = typedArray.getDimensionPixelSize(attr,16);
                    break;
                case R.styleable.BarGraphView_maxLimit:
                    maxLimit = typedArray.getInt(attr,100);
                    break;
                case R.styleable.BarGraphView_unit:
                    unit = typedArray.getString(attr);
                    break;
            }
        }
        typedArray.recycle();//释放掉

        mPaint = new Paint();
        mPaint.setColor(titleColor);
        mPaint.setTextSize(titleSize);
        mPaint.setAntiAlias(true);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        width = getWidth();
        height = getHeight();
        Rect mBound = new Rect();
        mPaint.getTextBounds(title,0,title.length(),mBound);
        int titleHeight = sp2px((int) titleSize);
        canvas.drawText(title,(width-mBound.width())/2,titleHeight-15,mPaint);
        int charWidth = width - dp2px(50);
        float charHeight = height - dp2px(70);
        Paint linePaint = new Paint(mPaint);
        linePaint.setColor(Color.DKGRAY);
        linePaint.setTextSize(3);
        //画X轴
        canvas.drawLine(dp2px(30), charHeight + titleHeight, charWidth + dp2px(30), charHeight + titleHeight, linePaint);
        //画Y轴
        canvas.drawLine(dp2px(30), titleHeight, dp2px(30), charHeight + titleHeight, linePaint);
        //计算单位对应长度和左侧标记
        float d = charHeight/maxLimit; //单位对应长度
        float stepValue = maxLimit/5; //跨度
        int sHeight = (int) (charHeight/5); //实际绘制长度
        linePaint.setStrokeWidth(1);
        linePaint.setColor(Color.GRAY);
        linePaint.setTextSize(14);
        //画刻度线和刻度
        for (int i=0; i<5; i++){
            canvas.drawLine(dp2px(30), titleHeight+i*sHeight, charWidth + dp2px(30), titleHeight+i*sHeight, linePaint);
            canvas.drawText(maxLimit-i*stepValue+unit, dp2px(5), titleHeight+i*sHeight, linePaint);
        }
        //画零刻度
        canvas.drawText("0", dp2px(15), charHeight + titleHeight, linePaint);
        //画柱状图
        Paint barPaint = new Paint(mPaint);
        barPaint.setAntiAlias(true);
        barPaint.setStyle(Paint.Style.FILL);
        barPaint.setTextSize(sp2px(10));
        if (datas!=null&&datas.size()>0) {
            int barWidth = charWidth/datas.size()>60 ? 60 : charWidth/datas.size();
            for (int i=0; i<datas.size(); i++){
                canvas.save();
                CharData data = datas.get(i);
                int value = (int) data.getNumber();

                //int color = data.getColor()==0 ? colors[i%colors.length] : data.getColor();
                //设置颜色
                if (clickPos!=-1&&clickPos==i){
                    barPaint.setColor(Color.DKGRAY);
                }else{
                    barPaint.setColor(colors[i%colors.length]);
                }

                //在画柱状图
                canvas.drawRect(dp2px(30)+barWidth*i+5, charHeight+titleHeight-value*d,
                        dp2px(30)+barWidth*(i+1)-5, charHeight+titleHeight, barPaint);
                //在上方显示数值
                barPaint.setColor(Color.BLACK);
                canvas.drawText(value+"",dp2px(30)+barWidth*i+(int)(barWidth*0.3),charHeight+titleHeight-value*d-5,barPaint);
                //下方的字
//                canvas.drawText(data.getName(),dp2px(30)+barWidth*i+10,charHeight+titleHeight+30,barPaint);
                canvas.rotate(-90);
                Rect textBound = new Rect();
                barPaint.getTextBounds(data.getName(),0,data.getName().length(),textBound);
                canvas.drawText(data.getName(),-(charHeight + titleHeight+textBound.width()+8), (float) (dp2px(30)+barWidth*(i+0.6)),barPaint);
                canvas.restore();
            }
        }

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (datas!=null&&datas.size()>0){
            float stepWidth = (width - dp2px(50))/datas.size();
            float x = event.getX();
            for (int i=0; i<datas.size(); i++){
                if (x > dp2px(30)+stepWidth*i && x < dp2px(30)+stepWidth*(i+1)){
                    clickPos = clickPos==i ? -1 : i;
                    if (Looper.getMainLooper() == Looper.myLooper()) {
                        invalidate();
                    } else {
                        postInvalidate();
                    }
                }
            }
        }
        return super.onTouchEvent(event);
    }

    public void setDatas(List<CharData> datas) {
        this.datas = datas;
        invalidate();
    }

    private int dp2px(int value) {
        float v = getContext().getResources().getDisplayMetrics().density;
        return (int) (v * value + 0.5f);
    }

    private int sp2px(int value) {
        float v = getContext().getResources().getDisplayMetrics().scaledDensity;
        return (int) (v * value + 0.5f);
    }
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Android 自定义View之柱状图实践

快过年了,首先先给大家说声新年快乐!倘若你有了计划,便不会在道路上迷惘。遵从本心,毫不懈怠。新的一年,新的气象,2016年3月份,我和几个朋友写的猿计划App就要上线了,它来了并且告诉你:开发,不只是...

Android 如何 画 柱状图 -------自定义View

实现了 柱状图 根据 SeekBar的滑动 改变的效果: 图示效果: 自定义View的代码: package com.example.coustomviewdemo; ...

android之自定义View和ViewGroup(六)(代码篇,实现简单的走势图,柱状图同理)

项目需要走势图,什么柱状图、走势图,网上都有一堆现成的框架,但是我项目中只需要走势图,我用第三方框架简直是累赘,毕竟占大小,而且走势图也简单,所以就自己写了,好久没写博客了,就记下吧,供大家参考下,其...

自定义View画柱状图

  • 2015-11-18 10:48
  • 7.57MB
  • 下载

自定义View之柱状图

一.效果图 因项目需要自定义一个柱状图View及饼状图View,本文先主要介绍下自定义柱状图View,饼状图View下一篇介绍。 实现也很简单,大家可以先看下效果图: 二、实现步骤 代码也比较简单...

自定义view:快速实现柱状图的绘制

前言![这里写图片描述](http://img.blog.csdn.net/20161221165551388?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQ...

自定义组件之【柱状图】详解 已封装成View

http://www.eoeandroid.com/thread-83414-1-1.html先上图,里面的数据时伪数据,用的时候传入参数即可。柱状图会根据数值的大小来变换显示的颜色,比如绿色、土黄色...

自定义view之柱状图

因为公司项目需求,美工的设计图要我画一个柱状图表,我第一时间就想到了AChartEngine.jar这个玩意。但实际用起来却并没有达到设计图上的细节需求,抱着美工要猿画,猿不得不画的赴死精神,豁出去了...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)