自定义View之柱状图
来源:互联网 发布:怎么看linux的ip地址 编辑:程序博客网 时间:2024/05/19 03:21
一.效果图
因项目需要自定义一个柱状图View及饼状图View,本文先主要介绍下自定义柱状图View,饼状图View下一篇介绍,主要做个学习积累。
实现也很简单,大家可以先看下动态效果图:
二、实现步骤
代码也比较简单,就是遵循自定义View步骤顺序完成相应绘制,不清楚可以参考鸿祥大神的博客http://blog.csdn.net/lmj623565791。
1.定义HistogramView继承View,给HistogramView添加自定义属性:
以在value目录下找到attrs.xml文件,在文件中可以定义HistogramView用到的属性,比如颜色、字体大小等属性。文件内容如下:
<declare-styleable name="HistogramView"> <attr name="histogramItemWidth" format="dimension"/><!-- 柱状图项宽度 --> <attr name="topTextColor" format="color"/><!-- 顶部文字颜色 --> <attr name="topTextSize" format="dimension"/><!-- 顶部文字大小 --> <attr name="axesColor" format="color"/><!-- 坐标轴颜色 --> <attr name="axesTextColor" format="color"/><!-- 坐标轴文字颜色 --> <attr name="axesTextSize" format="dimension"/><!-- 坐标轴文字大小 --> </declare-styleable>
2.在.xml布局文件中对自定义的属性进行设置:
<com.cyj.histogramview.HistogramView android:id="@+id/histogramView" android:layout_width="match_parent" android:layout_height="280dp" android:layout_centerInParent="true" android:paddingTop="40dp" android:paddingLeft="10dp" android:layout_centerHorizontal="true" app:histogramItemWidth="20dp" app:axesColor="@color/black" app:axesTextColor="@color/mainColor" app:axesTextSize="12sp" app:topTextColor="@color/accentColor" app:topTextSize="13sp" android:background="@color/white"/>
3.在HistogramView的构造方法中获得自定义的属性,主要代码如下:
public HistogramView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.HistogramView); histogramItemWidth = typedArray.getDimension(R.styleable.HistogramView_axesTextSize, dp2px(20)); axesColor = typedArray.getColor(R.styleable.HistogramView_axesColor, getResources().getColor(R.color.accentColor)); axesTextColor = typedArray.getColor(R.styleable.HistogramView_axesTextColor, getResources().getColor(R.color.accentColor)); axesTextSize = typedArray.getDimension(R.styleable.HistogramView_axesTextSize, sp2px(12)); topTextColor = typedArray.getColor(R.styleable.HistogramView_topTextColor, getResources().getColor(R.color.accentColor)); topTextSize = typedArray.getDimension(R.styleable.HistogramView_topTextSize, sp2px(12)); typedArray.recycle(); init(); }
4.初始化画笔及一些必要变量,代码如下:
private void init() { ani = new HistogramAnimation(); ani.setDuration(2000); mMargin = dp2px(20); //初始化坐标轴画笔 mAexsPaint = new Paint(); mAexsPaint.setColor(axesColor); mAexsPaint.setAntiAlias(true); //坐标轴文字画笔 mAexsTextPaint = new TextPaint(); mAexsTextPaint.setStyle(Paint.Style.FILL); mAexsTextPaint.setColor(axesTextColor); mAexsTextPaint.setTextSize(axesTextSize); mAexsTextPaint.setAntiAlias(true); mAexsTextPaint.setTextAlign(Paint.Align.LEFT); //顶部文字画笔 mTopTextPaint = new TextPaint(); mTopTextPaint.setStyle(Paint.Style.FILL); mTopTextPaint.setColor(topTextColor); mTopTextPaint.setTextSize(topTextSize); mTopTextPaint.setAntiAlias(true); mTopTextPaint.setTextAlign(Paint.Align.LEFT); //柱状图画笔 mHistogramPaint = new Paint(); mHistogramPaint.setAntiAlias(true);// 抗锯齿效果 mHistogramPaint.setStyle(Paint.Style.FILL); mHistogramPaint.setColor(Color.parseColor("#9e95e9f3")); }
5.重写onDraw方法。在onDraw方法中完成柱状图的绘制。代码如下:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mWidth = getWidth() - getPaddingLeft() - getPaddingRight(); mHeight = getHeight(); histogramHeight = mHeight - bottomAxesTextHeight - getPaddingTop(); mMarginTop = getPaddingTop(); columWidth = (int) ((mWidth - mMargin) / columCount);//项的宽度 drawAxesLineAndAxes(canvas);//绘制坐标线及y轴刻度 drawAxesText(canvas);//绘制x轴值 drawHistogramItem(canvas);//绘制柱状图及柱状图上文字 }主要完全以下几个部分的绘制:
a.绘制坐标线及y坐标轴上的刻度,代码如下:
private void drawAxesLineAndAxes(Canvas canvas) { // 绘制底部的线条 canvas.drawLine(0, mHeight - bottomAxesTextHeight, mWidth, mHeight - bottomAxesTextHeight, mAexsPaint); // 绘制底部的线条 canvas.drawLine(mMargin, mMarginTop, mMargin, mHeight - bottomAxesTextHeight + mMargin, mAexsPaint); canvas.drawText("0", mMargin / 2, mHeight - bottomAxesTextHeight, mAexsTextPaint); canvas.drawText(maxValue + "", mMargin / 2, mHeight - bottomAxesTextHeight - histogramHeight, mAexsTextPaint); }
b.绘制x轴值
private void drawAxesText(Canvas canvas) { for (int i = 0; i < columCount; i++) { // 设置底部的文字 float textWidth = mAexsTextPaint.measureText(nameLists.get(i)); if (textWidth > columWidth) { textWidth = columWidth / 2; } else { textWidth = (columWidth - textWidth) / 2; } TextPaint textPaint = new TextPaint(); textPaint.setColor(axesTextColor); textPaint.setAntiAlias(true); textPaint.setTextSize(axesTextSize); StaticLayout layout = new StaticLayout(nameLists.get(i), textPaint, columWidth, Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, false); canvas.save(); canvas.translate((i) * columWidth + textWidth + mMargin, mHeight - bottomAxesTextHeight + mMargin / 2); layout.draw(canvas); canvas.restore();//别忘了restore } }
c.绘制柱状图及柱状图上的该项的值,代码如下:
private void drawHistogramItem(Canvas canvas) { // 绘制矩形 if (aniProgress != null && aniProgress.size() > 0) { for (int i = 0; i < aniProgress.size(); i++) {// 循环遍历将柱状图形画出来 int value = aniProgress.get(i); float left = (columWidth - histogramItemWidth) / 2 + i * columWidth + mMargin; float right = left + histogramItemWidth; float t = (maxValue) * 1000; float top = histogramHeight - histogramHeight * (value / t) + mMarginTop; float bottom = histogramHeight + mMarginTop; //进行paint设颜色 if (i % 4 == 0) { mHistogramPaint.setColor(getResources().getColor(R.color.subColor)); mTopTextPaint.setColor(getResources().getColor(R.color.subColor)); } else if (i % 4 == 1) { mHistogramPaint.setColor(getResources().getColor(R.color.subColor1)); mTopTextPaint.setColor(getResources().getColor(R.color.subColor1)); } else if (i % 4 == 2) { mHistogramPaint.setColor(getResources().getColor(R.color.subColor2)); mTopTextPaint.setColor(getResources().getColor(R.color.subColor2)); } else if (i % 4 == 3) { mHistogramPaint.setColor(getResources().getColor(R.color.subColor3)); mTopTextPaint.setColor(getResources().getColor(R.color.subColor3)); } RectF rect1 = new RectF(left, top, right, bottom);// 柱状图的形状 canvas.drawRoundRect(rect1, (histogramItemWidth) / 2, (histogramItemWidth) / 2, mHistogramPaint); //设置柱形上面的文字 float textWidth = mTopTextPaint.measureText(countLists.get(i)); if (textWidth > columWidth) { textWidth = 0; } else { textWidth = (columWidth - textWidth) / 2; } canvas.drawText(countLists.get(i) + "", (i) * columWidth + textWidth + mMargin, top - dp2px(10), mTopTextPaint); } } }
在这一步不断改变柱状图的高度,使柱状图有个动画效果,使高度不断改变可以通过如下动画类实现:
/** * 集成animation的一个动画类 */ private class HistogramAnimation extends Animation { protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); for (int i = 0; i < aniProgress.size(); i++) { aniProgress.set(i, (int) (Integer.parseInt(countLists.get(i)) * 1000 * interpolatedTime)); } invalidate(); } }
三、使用
在Activity中初始化柱状图数据,并开启动画效果:
ArrayList<String> nameLists = new ArrayList<>(); ArrayList<String> countLists = new ArrayList<>(); for (int i=0;i<8;i++){ nameLists.add("项"+i); countLists.add(""+new Random().nextInt(20)); } histogramView.start(nameLists,countLists); }}
上面已经贴出了实现的关键代码,完整demo可以参考:https://github.com/yjchen920927/HistogramView
0 0
- 自定义view之柱状图
- 自定义View之柱状图
- Android 自定义View之柱状图实践
- 自定义view柱状图
- 自定义组件之【柱状图】详解 已封装成View
- 自定义view-3d柱状图
- Android自定义View写柱状图
- 自定义控件之柱状图
- 自定义View实例(四)----自定义条形柱状图
- Android 如何 画 柱状图 -------自定义View
- [AndroidUI]自定义view(五):实现动态柱状图
- 【Android】自定义View -- 条形图(柱状图)
- Android自定义View(三)柱状图
- 28 自定义View画坐标和柱状图
- Android自定义View——柱状图
- 自定义view:快速实现柱状图的绘制
- 二、关于自定义view的文章:柱状图
- 自定义View-轻量级柱状图、饼图、折线图
- LintCode-两数组的交集
- spring 回滚事务 异常处理 手动回滚 公司通用处理方式
- Web基础之与Tomcat的初次相遇
- 快排和堆排序
- 关于HTML--结构化标签
- 自定义View之柱状图
- 关于Java面向对象之封装
- 杭电acm1016 Prime Ring Problem
- Java创建线程(Runnable接口和Thread类)
- 有关socket通信包大小的问题总结(UDP传输模式)
- 传奇客户度文件代码完全解析
- Collection和Map的那些常用的类操作的实现原理简要理解笔记
- 函子
- Makefile经典教程(一个很棒很清晰的讲解)