【第22期】观点:IT 行业加班,到底有没有价值?

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自定义横向柱状图

上图: 类似于这样的效果,很简单。这是一个listview,item是自定义的view,有两个特点:   传入长度,动态改变柱状图的长度;根据长度改变色值,长度越长越红,反之越黄。   ...

Android性能优化典范

http://hukai.me/android-performance-patterns/ 2015新年伊始,Google发布了关于Android性能优化典范的专题,一共16个短视频,每个3-5分钟,帮助开发者创建更快更优秀的Android App。课程专题不仅仅介绍了Android系统中有关...

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

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

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

android开源项目总结

<spa

Android自定义View柱状图的绘制总结

Android自定义View柱状图的绘制总结       前面简单介绍了绘制折线图,博客: http://blog.csdn.net/wenzhi20102321/article/details/6...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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