上一节当中,我们主要看了下ChartFactory类的getDoughnutChartIntent方法如何产生了一个intent对象,并给其赋值,从而实现界面跳转,这一节,我们来看一下具体的显示的界面上的view的完整绘制过程,我们接着上一节往下进行。
public void add(String category, String[] titles, double[] values)
{
this.mCategories.add(category);
this.mTitles.add(titles);
this.mValues.add(values);
}
{
paint.setAntiAlias(this.mRenderer.isAntialiasing());
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(this.mRenderer.getLabelsTextSize());
int legendSize = getLegendSize(this.mRenderer, height / 5, 0.0F);
int left = x;
int top = y;
int right = x + width;
int cLength = this.mDataset.getCategoriesCount();
String[] categories = new String[cLength];
for (int category = 0; category < cLength; ++category) {
categories[category] = this.mDataset.getCategory(category);
}
if (this.mRenderer.isFitLegend()) {
legendSize = drawLegend(canvas, this.mRenderer, categories, left, right, y, width, height, legendSize, paint, true);
}
int bottom = y + height - legendSize;
drawBackground(this.mRenderer, canvas, x, y, width, height, paint, false, 0);
this.mStep = 7;
int mRadius = Math.min(Math.abs(right - left), Math.abs(bottom - top));
double rCoef = 0.35D * this.mRenderer.getScale();
double decCoef = 0.2D / cLength;
int radius = (int)(mRadius * rCoef);
if (this.mCenterX == 2147483647) {
this.mCenterX = ((left + right) / 2);
}
if (this.mCenterY == 2147483647) {
this.mCenterY = ((bottom + top) / 2);
}
float shortRadius = radius * 0.9F;
float longRadius = radius * 1.1F;
List prevLabelsBounds = new ArrayList();
for (int category = 0; category < cLength; ++category) {
int sLength = this.mDataset.getItemCount(category);
double total = 0.0D;
String[] titles = new String[sLength];
for (int i = 0; i < sLength; ++i) {
total += this.mDataset.getValues(category)[i];
titles[i] = this.mDataset.getTitles(category)[i];
}
float currentAngle = this.mRenderer.getStartAngle();
RectF oval = new RectF(this.mCenterX - radius, this.mCenterY - radius, this.mCenterX + radius, this.mCenterY + radius);
for (int i = 0; i < sLength; ++i) {
paint.setColor(this.mRenderer.getSeriesRendererAt(i).getColor());
float value = (float)this.mDataset.getValues(category)[i];
float angle = (float)(value / total * 360.0D);
canvas.drawArc(oval, currentAngle, angle, true, paint);
drawLabel(canvas, this.mDataset.getTitles(category)[i], this.mRenderer, prevLabelsBounds, this.mCenterX, this.mCenterY, shortRadius, longRadius, currentAngle, angle, left, right, this.mRenderer.getLabelsColor(), paint, true, false);
currentAngle += angle;
}
radius = (int)(radius - (mRadius * decCoef));
shortRadius = (float)(shortRadius - (mRadius * decCoef - 2.0D));
if (this.mRenderer.getBackgroundColor() != 0)
paint.setColor(this.mRenderer.getBackgroundColor());
else {
paint.setColor(-1);
}
paint.setStyle(Paint.Style.FILL);
oval = new RectF(this.mCenterX - radius, this.mCenterY - radius, this.mCenterX + radius, this.mCenterY + radius);
canvas.drawArc(oval, 0.0F, 360.0F, true, paint);
--radius;
}
prevLabelsBounds.clear();
drawLegend(canvas, this.mRenderer, categories, left, right, y, width, height, legendSize, paint, false);
drawTitle(canvas, x, y, width, paint);
}
1:ChartFactory.getDoughnutChartIntent方法的第二个参数为
MultipleCategorySeries
,通过add方法,将
double[] values值加入到成员就是
List mValues中,这里一定要注意,
传过来的参数titles、values的长度必须一致,因为在for循环中是以values的下标来取,而且每次都要取titles,如果长度不一致,会导致下标越界异常,
MultipleCategorySeries类的add方法源码如下:
{
this.mCategories.add(category);
this.mTitles.add(titles);
this.mValues.add(values);
}
2:将构建好的
MultipleCategorySeries
参数名为
dataset传给
DoughnutChart chart = new DoughnutChart(dataset, renderer),构建一个
DoughnutChart对象,通过
intent.putExtra("chart", chart)把
DoughnutChart传
递到下一个页面,同时程序执行界面
跳转
,到
GraphicalActivity中,取出传递过来的
this.mChart = ((AbstractChart)extras.getSerializable("chart"))参数,传递给
this.mView = new GraphicalView(this, this.mChart),构建一个
GraphicalView对象,显示到界面上,
在
GraphicalView的构造方法中执行else循环,因为传递过来的是
DoughnutChart,继承自
RoundChart,取出
getRenderer()对象并赋值给成员变量
this.mRenderer,注意此时的
mRenderer对象是在
DoughnutChart chart = new DoughnutChart(dataset, renderer)方法中传递过来的,调用父类
RoundChart的构造方法
super(null, renderer)方法,
赋值给了成员变量
this.mRenderer = renderer,此处执行的源码如下:
if (this.mChart instanceof XYChart)
this.mRenderer = ((XYChart)this.mChart).getRenderer();
else {
this.mRenderer = ((RoundChart)this.mChart).getRenderer();
}
this.mRenderer = ((XYChart)this.mChart).getRenderer();
else {
this.mRenderer = ((RoundChart)this.mChart).getRenderer();
}
3:继续往下执行,
if (this.mRenderer.isZoomButtonsVisible()),我们来看一下传过来的
renderer,从
AbstractDemoChart类的
buildCategoryRenderer方法一直到调在用到
renderer,整个路径中没有调用
DefaultRenderer的
setZoomButtonsVisible方法,所有
isZoomButtonsVisible是在构造方法中
this.mZoomButtonsVisible = false
赋初始值为false,因此,此分支不执行
继续往下看,
if ((this.mRenderer instanceof XYMultipleSeriesRenderer ) && (((XYMultipleSeriesRenderer )this.mRenderer).getMarginsColor() == 0)),我们传进来的是一个
DefaultRenderer对象,是
XYMultipleSeriesRenderer 类的父类,因此,第一个括号值为false,执行&&判断后,还为false,此分支不执行
4:
继续往下执行,
if (((this.mRenderer.isZoomEnabled()) && (this.mRenderer.isZoomButtonsVisible())) || (this.mRenderer.isExternalZoomEnabled())),
isZoomEnabled属性在构造方法初始化中
this.mZoomEnabled = true初始化为true,
isZoomButtonsVisible在构造方法中初始化为false,
isExternalZoomEnabled属性在构造方法中
this.mExternalZoomEnabled = false初始化为false,此分支值为false,不执行
5:
继续往下执行,
GraphicalActivity执行
setContentView(this.mView)方法添加
GraphicalView时,会调用
onDraw方法,第一个分支判断,
if (this.mRenderer.isInScroll()),
mRenderer从始至终未赋值,初始化为false,此分支不执行,
if ((this.mRenderer != null) && (this.mRenderer.isZoomEnabled())
&& (this.mRenderer.isZoomButtonsVisible()))分支值为false,也不执行,那么最终绘制view就是在
this.mChart.draw(canvas, left, top, width, height, this.mPaint)这句当中执行的,我们可以看一下log的输出顺序,即可明白程序的执行,图片如下:
6:
继续往下执行,进入
DoughnutChart的
draw方法中,我们可以看到,所显示出来的圆圈view就是在这里绘制完成的,其中的
sLength值为5,即为我们传进来的五种颜色,for循环执行5次,画出每个环圈,最终形成一个view,显示在我们的界面上,
源码如下:
public void draw(Canvas canvas, int x, int y, int width, int height, Paint paint)
Google开源图标库这acharengine源码分析就为大家讲到这,欢迎大家收藏、评论、转载,如有问题,也可联系我QQ:1531074759,谢谢大家!