最近的项目一直在和图表库MPAndroidChart打交道,很庆幸的是这个库功能相当强大,几乎能满足各类统计的功能。但就在不久前,UI给出的效果图是带圆角的柱状渐变图,经过一番查找,发现该库渐变色倒是提供了,并没有圆角的设置。
初始效果:
目标效果:
几经转折,最后在Github的lssues中发现很早之前便有人提出过这个需求,但得到的回复大致意思:是这个需求太小太精细了,微不足道,不值得添加。但我也从提问者描述得知其中有个BarChartRenderer的类,那就顺藤摸瓜,看看这个类中到底做了些什么。
在BarChart的初始化方法中默认设置了这个类,看名字就知道这是关于渲染的一个类
protected void init() {
super.init();
mRenderer = new BarChartRenderer(this, mAnimator, mViewPortHandler);
......
}
既然这样,那么我是不是可以自定义这么一个类,让它渲染我想要的任何效果呢?
进入到源码,经过一番研究发现,我们需要关心的只有drawHighlighted和drawDataSet两个方法。前者是高亮时的绘制,如果不使用高亮效果可以忽略,后者便是我们正常渲染柱状图的方法。源代码通过drawRect的方式画矩形,而我们需要drawRoundRect画圆角。但drawRoundRect画的是四个圆角,所以还需要一点小技巧:
while (j < buffer.size()) {
....
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
buffer.buffer[j + 3], mBarBorderPaint);
j += 4
....
}
源代码是一段一段绘制Rect,那么我们完全可以将最上面的一段绘制为圆角,在绘制下面一段的时候接上无圆角的矩形。或者整个绘制为有圆角的矩形,最下面一段在叠上一个无圆角的矩形。当然还可利用交集并集等处理方式,怎么方便怎么来。附上关键代码:
val rectF = RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],buffer.buffer[j + 3])
if (j % 4 == 0) {
c.drawRect(
buffer.buffer[j],
(buffer.buffer[j + 1] + buffer.buffer[j + 3]) / 2,
buffer.buffer[j + 2],
buffer.buffer[j + 3],
mRenderPaint
)
} else {
c.drawRect(rectF, mRenderPaint)
}
//这里采用drawRoundRect画圆角 其实是和drawRect重叠的效果
c.drawRoundRect(rectF, 30f, 30f, mRenderPaint)
if (drawBorder) {
c.drawRoundRect(rectF, 30f, 30f, mBarBorderPaint)
}
j += 4
以上有个关键的地方是if (j % 4 == 0) 判断,按照源码意思j是每次递增4的,所以每一次递增就得给矩形加一个圆角,否则柱状图只会第一个生效,后面的则没有圆角效果。
最后:
barChart.apply {
......
renderer= BarChartRenderer(this,animator, viewPortHandler)
......
以上便是柱状图实现圆角的方法,希望对大家有所帮助**!**