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自定义带动画的柱状图控件

1.也是突然的想法,写了个柱状图,然后觉得静态的太死板又加上去了动画和点击事件. 2.下面开始上菜!各位道友觉得不好呢,就多给点批评建议,然后都给点个赞,哈哈~(原创作品,转载请标明) (上传图片...

Android 自定义View之柱状图实践

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

Android 项目(一):自定义View绘制“柱状图”

为什么要绘制柱状图?这是因为在有些应用中需要展示数据,单纯的列出一些数据估计谁看了都会烦,因此数据的展示通常会使用一些图表的形式展现出来。   上面的柱子是怎样绘制的呢?先来梳理一下思路:通过上面的...

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

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

android自定义view-3d柱状图

最近,项目里需要加入3d柱状图展示数据,在网上找了找,发现和需求有点出入(可能自己没找对),于是就自己画了个,随便锻炼下自己,下面就把这个demo写出来。public class CustomBar ...
  • jwmxxx
  • jwmxxx
  • 2016年05月02日 09:55
  • 178

【Android】自定义View -- 条形图(柱状图)

【问题】 实现可动态变化的条形图; 【效果图】 【用法】 How to use1? android:id="@+id/dcv_7" ...

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

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

自定义View画柱状图

  • 2015年11月18日 10:48
  • 7.57MB
  • 下载

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

前言![这里写图片描述](http://img.blog.csdn.net/20161221165551388?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android自定义View(三)柱状图
举报原因:
原因补充:

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