自定义绘制柱形图
时间:2022-04-25
本文章向大家介绍自定义绘制柱形图,主要内容包括设计思路:、2.画竖线和文字、3.画顶部横线、使用方法、完整代码、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
设计思路:
1.画柱状图 2.画竖线 3.画顶部横线 4.画文字
1.画柱状图
画柱状图的方法很简单,就是使用canvas.drawRect(float left, float top, float right, float bottom, Paint paint),其实这里我遇到了一个问题,一开始我想只画一条柱状图,然后需要几个柱状图就在xml文件中声明几个,后来我发现,这样实现起来的动画非常之卡顿(上面gif录出来看上去很卡,其实很流畅)。后来我就换了一种思路,就是声明一个数组,在Activity传入我们需要画的柱状图的总个数和每个柱状图的目标值大小,然后在onDraw方法里分别计算每个柱状图的当前进度,然后分别画出来,这样动画效果就非常流畅了。
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 画柱状图
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> ; i<totalBarNum ; i++){
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (currentBarProgress[i]<(respTarget.get(i)/max)*stopX) {
currentBarProgress[i]+=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;
postInvalidateDelayed(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>);
}
canvas.drawText(respName.get(i),startX,startY+deltaY+i*(deltaY+barWidth)+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>*barWidth/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>, mTextPaint);
canvas.drawRect(startX+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>*barWidth/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>, startY+deltaY+i*(deltaY+barWidth), currentBarProgress[i], startY+deltaY+i*(deltaY+barWidth)+barWidth, mBarPaint);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
2.画竖线和文字
有了上面画柱状图的思路,画竖线就非常容易想了,和画柱状图是一个思路,也是Activity中传入需要画几条竖线,然后在onDraw方法里分别去计算他们的当前进度值,然后再分别去画
文字大小应该随着柱形图宽度来自动适应,所以我进行了一些计算,看上去很复杂,其实就是为了自适应文字的大小
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 画竖线
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> ; i<verticalLineNum ; i++){
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (currentVerticalLineProgress< measuredHeight) {
currentVerticalLineProgress+=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;
postInvalidateDelayed(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>);
}
canvas.drawLine((startX+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>*barWidth/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>)+(i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)*deltaX, startY, (startX+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>*barWidth/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>)+(i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)*deltaX, currentVerticalLineProgress, mLinePaint);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//画文字</span>
canvas.drawText(numPerUnit*(i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)+unit, (startX+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>*barWidth/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>)+(i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)*deltaX-barWidth, startY-barWidth/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>, mTextPaint);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>
3.画顶部横线
顶部横线我是从右向左画的,正好与柱状图形成一个对比
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 画最上面的横线
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (currentHorizentalLineProgress>startX+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>*barWidth/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>) {
currentHorizentalLineProgress-=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;
postInvalidateDelayed(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>);
}
canvas.drawLine(stopX, startY, currentHorizentalLineProgress, startY, mLinePaint);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
使用方法
1.设置柱状图的最大值
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">mBarGraph<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setMax</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">40</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
2.设置柱状图单位
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">mBarGraph<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setUnit</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"亿元"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
3.设置柱状图宽度
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">mBarGraph<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setBarWidth</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">50</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
4.设置竖线条数
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">mBarGraph<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setVerticalLineNum</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
5.设置柱状图总个数
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> mBarGraph<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTotalBarNum</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
6.设置每个柱状图的目标值
<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> private ArrayList<Float> respectTarget;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
respectTarget = new ArrayList<Float>();
respectTarget.add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">35.</span>0f);
respectTarget.add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20.</span>0f);
respectTarget.add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">18.</span>0f);
respectTarget.add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">15.</span>0f);
respectTarget.add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10.</span>0f);
respectTarget.add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8.</span>0f);
respectTarget.add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5.</span>0f);
mBarGraph.setRespectTargetNum(respectTarget);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
7.设置每个柱状图的名字
<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">private ArrayList<String> respName;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
respName = new ArrayList<String>();
respName.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"滴滴"</span>);
respName.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"小米"</span>);
respName.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"京东"</span>);
respName.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"美团"</span>);
respName.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"魅族"</span>);
respName.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"酷派"</span>);
respName.add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"携程"</span>);
mBarGraph.setRespectName(respName);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
完整代码
大家可以上我的GitHub上下载完整代码
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- TensorBoard可视化
- Java自动化测试(Maven 8)
- Java自动化测试(HashSet和HashMap 7)
- 构建模型的3种方法
- 训练模型的3种方法
- 干货 | 携程APP/Web功能和视觉测试平台-Watcher
- FPGA中的亚稳态
- 蜂鸟E203系列——定时器中断设计
- FPGA信号截位策略
- 数字IC设计经典笔试题之【verilog篇】
- 蜂鸟E203系列——Windows下运行hello world例程
- 蜂鸟E203系列——Windows开发工具
- FPGA奇数分频
- 形式化分析工具:在虚拟操作系统和主机操作系统之间配置共享文件夹
- 「PHP」以nginx、php-cgi为例,把nginx、php-cgi安装为Windows系统服务