前几天在做一个Android app的时候,需要画一个饼图,直接用代码自己画一个当然也不会太复杂,但毕竟还是应该尽量避免重新发明轮子(有些愤青连这句话也要吐槽,好吧,加上一句,专业制造轮子的除外),在网上找了一圈下来,发现可用的库寥寥可数,aiCharts确实不错,可惜是商业化产品,免费试用的有水印,不太适合用在我的app里面,最后决定用DroidCharts,一个JFreeCharts的Android移植版本
目前DroidCharts已经实现了下面几种图:
- pie chart
- line chart
- xy line chart
- bar chart
- category bar chart
可惜文档资料不太齐全(快2年没更新了,很可能要太监),不过既然是移植自JFreeCharts,倒也不用担心使用上的问题,所以我还是选用它
官方网站目前只有源代码,这里是已经打好包的库,可以下载后作为第三方库加入app,步骤如下:
- 在工程所在目录中创建libs子目录
- 复制DroidCharts.jar到新建的libs目录下面
- 刷新Package Explorer,libs/DroidCharts.jar
- 打开工程的Java Build Path,选中Libraries选项卡,点击Add JARs...按钮,选择libs/DroidCharts.jar
这时候可能会看到一行错误提示:
Error generating final archive: Found duplicate file for APK: res/layout/main.xml
这是因为DroidCharts.jar包里面已经有layout名字叫main.xml,而当前应用的layout里面也有main.xml,没办法,这种情况下只能把自己的main.xml改个名字了
正常情况下,因为打包了DroidCharts库,这时候查看apk文件会发现长度增加了几百K
接下来增加一个PieChartView,继承自android.view.View
PieChartView.java
import net.droidsolutions.droidcharts.awt.Font;
import net.droidsolutions.droidcharts.awt.Rectangle2D;
import net.droidsolutions.droidcharts.core.ChartFactory;
import net.droidsolutions.droidcharts.core.JFreeChart;
import net.droidsolutions.droidcharts.core.data.DefaultPieDataset;
import net.droidsolutions.droidcharts.core.data.PieDataset;
import net.droidsolutions.droidcharts.core.plot.PiePlot;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
public class PieChartView extends View {
/** The view bounds. */
private final Rect mRect = new Rect();
/** The user interface thread handler. */
private final Handler mHandler;
public PieChartView(Context context) {
this(context, null);
}
public PieChartView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PieChartView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mHandler = new Handler();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.getClipBounds(mRect);
final PieDataset dataset = createDataset();
final JFreeChart chart = createChart(dataset);
chart.draw(canvas, new Rectangle2D.Double(0, 0, mRect.width(), mRect
.height()));
}
/**
* Schedule a user interface repaint.
*/
public void repaint() {
mHandler.post(new Runnable() {
public void run() {
invalidate();
}
});
}
private PieDataset createDataset() {
DefaultPieDataset ds = new DefaultPieDataset();
ds.setValue("已用空间", 56);
ds.setValue("占用空间", 18);
ds.setValue("剩余空间", 32);
return ds;
}
private JFreeChart createChart(final PieDataset dataset) {
// create the chart...
final JFreeChart chart = ChartFactory.createPieChart(null, dataset, false, false, false);
Paint black = new Paint(Paint.ANTI_ALIAS_FLAG);
black.setColor(Color.BLACK);
chart.setBackgroundPaint(black);
chart.setBorderVisible(false);
Paint color0 = new Paint(Paint.ANTI_ALIAS_FLAG);
color0.setColor(Color.YELLOW);
Paint color1 = new Paint(Paint.ANTI_ALIAS_FLAG);
color1.setColor(Color.BLUE);
Paint color2 = new Paint(Paint.ANTI_ALIAS_FLAG);
color2.setColor(Color.GREEN);
final PiePlot plot = (PiePlot)chart.getPlot();
plot.setBackgroundPaint(black);
plot.setSectionPaint("已用空间", color0);
plot.setSectionPaint("占用空间", color1);
plot.setSectionPaint("剩余空间", color2);
// 设置默认字体
plot.setLabelFont(new Font());
// 不显示文本
plot.setLabelGenerator(null);
// 设置开始角度为12点钟方向
plot.setStartAngle(-90);
return chart;
}
}
编辑layout的xml文件,把PieChartView加入layout
如:
要注意的是,这里必须写全名your.packet.name.PieChartView,否则抛出找不到类的异常
切回图形模式,可以看到PieChartView的预览窗口
顺便说一下,为了能在图形模式下能够正常预览PieChartView,我在ChartFactory.createPieChart时把title参数设为null,另外加了一行代码plot.setLabelFont(new Font()),否则在预览PieChartView的时候,将会因为绘制title和label缺乏默认字体对象而抛出空指针的异常(可能是DroidCharts的BUG)
感谢:
http://code.google.com/p/droidcharts/
http://w2davids.wordpress.com/creating-charts-with-droidcharts-for-android/