最近一个项目里面要实现这种UI界面,由于之前没做过类似的表格,当时就无从下手。但从网上了解到Achartengine开源框架可以实现很多表格图,然后就下载jar包集成到自己的项目里面。
慢慢的研究下,还是把表格画出来了。原生的Achartengine里面有mRenderer.setFillBelowLine(true)和mRenderer.setFillBelowLineColor(Color.parseColor("#ffE3A505"))这个2方法来实现这下面的背景颜色设置,mRenderer是单条曲线渲染器(XYSeriesRenderer)。但是原生的背景颜色设置是单一的,没有我要的这样颜色的渐变效果。我要强烈的吐槽下,为什么没有渐变的效果!!!
没有办法,只能站在巨人的肩膀上修改它的源码了。记住,在看它的源码的时候千万不要从头开始看,我感觉那样没有必要。我们只是要实现一个背景颜色渐变的效果,只要找准入口的位子就事半功倍了。mRenderer.setFillBelowLineColor(Color.parseColor("#ffE3A505"))是它用来设置背景颜色的方法,那我们就从这里入口,看它是怎么把背景颜色画出来的。
点到最后就这样的,我们做的就是setColor()的工作。既然我们设置的颜色,它肯定要取出来啊。它上面果然有个getColor()的方法,继续走近去,看那个地方调用了这个方法。
哇!!!整个框架里面就一个地方调用了这个方法,减少了我很多的麻烦。再看看里面都是些什么鬼。
public void drawSeries(Canvas canvas, Paint paint, List<Float> points, XYSeriesRenderer renderer, float yAxisValue, int seriesIndex, int startIndex) { float lineWidth = paint.getStrokeWidth(); paint.setStrokeWidth(renderer.getLineWidth()); final FillOutsideLine[] fillOutsideLine = renderer.getFillOutsideLine(); for (FillOutsideLine fill : fillOutsideLine) { if (fill.getType() != FillOutsideLine.Type.NONE) { paint.setColor(fill.<span style="color:#ff0000;background-color: rgb(255, 255, 255);">getColor()</span>); // TODO: find a way to do area charts without duplicating data List<Float> fillPoints = new ArrayList<Float>(); int[] range = fill.getFillRange(); if (range == null) { fillPoints.addAll(points); } else { if (points.size() > range[0] * 2 && points.size() > range[1] * 2) { fillPoints.addAll(points.subList(range[0] * 2, range[1] * 2)); } } final float referencePoint; switch (fill.getType()) { case BOUNDS_ALL: referencePoint = yAxisValue; break; case BOUNDS_BELOW: referencePoint = yAxisValue; break; case BOUNDS_ABOVE: referencePoint = yAxisValue; break; case BELOW: referencePoint = canvas.getHeight(); break; case ABOVE: referencePoint = 0; break; default: throw new RuntimeException( "You have added a new type of filling but have not implemented."); } if (fill.getType() == FillOutsideLine.Type.BOUNDS_ABOVE || fill.getType() == FillOutsideLine.Type.BOUNDS_BELOW) { List<Float> boundsPoints = new ArrayList<Float>(); boolean add = false; int length = fillPoints.size(); if (length > 0 && fill.getType() == FillOutsideLine.Type.BOUNDS_ABOVE && fillPoints.get(1) < referencePoint || fill.getType() == FillOutsideLine.Type.BOUNDS_BELOW && fillPoints.get(1) > referencePoint) { boundsPoints.add(fillPoints.get(0)); boundsPoints.add(fillPoints.get(1)); add = true; } for (int i = 3; i < length; i += 2) { float prevValue = fillPoints.get(i - 2); float value = fillPoints.get(i); if (prevValue < referencePoint && value > referencePoint || prevValue > referencePoint && value < referencePoint) { float prevX = fillPoints.get(i - 3); float x = fillPoints.get(i - 1); boundsPoints.add(prevX + (x - prevX) * (referencePoint - prevValue) / (value - prevValue)); boundsPoints.add(referencePoint); if (fill.getType() == FillOutsideLine.Type.BOUNDS_ABOVE && value > referencePoint || fill.getType() == FillOutsideLine.Type.BOUNDS_BELOW && value < referencePoint) { i += 2; add = false; } else { boundsPoints.add(x); boundsPoints.add(value); add = true; } } else { if (add || fill.getType() == FillOutsideLine.Type.BOUNDS_ABOVE && value < referencePoint || fill.getType() == FillOutsideLine.Type.BOUNDS_BELOW && value > referencePoint) { boundsPoints.add(fillPoints.get(i - 1)); boundsPoints.add(value); } } } fillPoints.clear(); fillPoints.addAll(boundsPoints); } int length = fillPoints.size(); if (length > 0) { fillPoints.set(0, fillPoints.get(0) + 1); fillPoints.add(fillPoints.get(length - 2)); fillPoints.add(referencePoint); fillPoints.add(fillPoints.get(0)); fillPoints.add(fillPoints.get(length + 1)); for (int i = 0; i < length + 4; i += 2) { if (fillPoints.get(i + 1) < 0) { fillPoints.set(i + 1, 0f); } } <span style="color:#ff0000;">paint.setStyle(Style.FILL);</span> <span style="background-color: rgb(255, 255, 255);"><span style="color:#ff0000;">drawPath(canvas, fillPoints, paint, true);</span></span> } } } paint.setColor(renderer.getColor()); paint.setStyle(Style.STROKE); drawPath(canvas, points, paint, false); paint.setStrokeWidth(lineWidth); }上面我标了红色的地方都是很重要的代码。我们之前设置的颜色就是在fill. getColor()里被取出来了,再看看它画笔 paint.setStyle(Style.FILL),设置的是填充,很明显,背景颜色就是用这支笔画出来的,然后再调用 drawPath(canvas, fillPoints, paint, true)。到这里大家应该很清楚的知道,它是怎么画的背景颜色的了吧。要想实现我们自己的颜色渐变效果只需要用一只有颜色渐变效果的笔就行了。但是这个地方要非常的注意,千万不要修改它的笔,因为它整个框架里面都是用的这一支笔,改了之后,你其它的图都会出现颜色上的错误,自己写一支笔就行了。但是怎么让笔有颜色渐变效果,这里就不多讲了,自己可以查,网上也有很多,写得都比我好,在这里我就不在写了。
我把改好的源码jar包放在了云盘里,地址 https://yunpan.cn/cP4tqsDEUjtkY 访问密码 e4a4我的资源里面也有,里面增加背景颜色渐变效果的API,只需调用 Yaohui.setYaohui(true)和 Yaohui.setLg(new LinearGradient(130, 100, 130, 250, colors, positions, TileMode.CLAMP))就可以实现渐变的效果了,但是前提是一定要设置mRenderer.setFillBelowLine(true),要不是没有效果的。好了就到了,虽然写的不是特别好,但是大家觉得有用的话希望顶一下,谢谢啦!!!