「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」
安卓中如何快速的绘制饼状图
在很多的场景中,大家都要用到图表类型,虽然很多人都有使用自定义视图的能力,但在一般的工作中,大家一般还是用轮子的比较多。原因也很简单,自己使用原生代码去写,需要熟练运用自定义视图的知识,其次需要花费大量的时间,最后还要解决解决bug。著名的图表库已经可以很大程度的满足需求了,即使有些定制化的需求,通过修改这些轮子也能达到效果。
一、选择图表库
筛选最著名的两个图表库
截止到目前,他们的Star分别是 7.3K、34.5K.
当然是选择星星比较多的啦。
因为星星多的库,一般生态也会比较大,遇到疑难杂症就比较容易搜索出来。
二、效果图
三、抛出几个问题
-
当数据值为0时怎么在饼状图上显示?
-
当饼状图中数据很多时,数据重叠怎么办?
四、开始编码
4.1 引入图标库
// 引入图表
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
并且,在安卓开发工具北极狐上,需要在项目根目录的settings.gradle
添加代码
repositories {
maven { url "https://jitpack.io" }
}
4.2 XML中引入视图
<com.github.mikephil.charting.charts.PieChart
android:id="@+id/pie_chart"
android:layout_width="match_parent"
android:layout_height="match_parent" />
4.3 构建数据
一般来说,我们需要的数据结构是 标签+数据,比如:张三+分数,所以我们构建出这个对象。
class ChartBean {
private String label;
private int value;
}
我们构建多一点,为了模拟0分的现象,我们也构建两个零分的数据。
private List<ChartBean> getData() {
List<ChartBean> list = new ArrayList<>();
list.add(new ChartBean("张三", 1));
list.add(new ChartBean("李四", 2));
list.add(new ChartBean("王五", 3));
list.add(new ChartBean("赵六", 4));
list.add(new ChartBean("孙七", 0));
list.add(new ChartBean("周八", 0));
return list;
}
4.4 添加配置
有一些很常用的配置,比如说
去除右下角的描述 -> getDescription().setEnabled(false)
实心圆 或 空心圆 -> setDrawHoleEnabled(false);
不使用百分比 -> setUsePercentValues(false);
为了方便大家拷贝,我把initPieChart贴出来。
private void initPieChart(PieChart pieChartView, @NonNull List<ChartBean> chartResultBeans) {
pieChartView.setVisibility(View.VISIBLE);
pieChartView.setRotationAngle(45);
// 去除 右下角的描述
pieChartView.getDescription().setEnabled(false);
// 实心圆 或 空心圆
pieChartView.setDrawHoleEnabled(false);
// 不使用百分比,不然会被计算
pieChartView.setUsePercentValues(false);
// 隐藏label,设置 label 文字大小
pieChartView.setDrawEntryLabels(false);
pieChartView.setEntryLabelTextSize(24);
// 设置legend 文字大小
pieChartView.getLegend().setTextSize(20);
pieChartView.getLegend().setTextColor(Color.WHITE);
// 构建数据
List<PieEntry> strings = new ArrayList<>();
for (ChartBean bean : chartResultBeans) {
if (bean != null) {
if (bean.getValue() == 0)
strings.add(new PieEntry(0.3f, bean.getLabel(), bean));
else
strings.add(new PieEntry(bean.getValue(), bean.getLabel(), bean));
}
}
// 右下角的label 不需要
PieDataSet dataSet = new PieDataSet(strings, "");
// 添加颜色(添加多种,避免造成颜色一样的情况)
ArrayList<Integer> colors = new ArrayList<>();
colors.add(getResources().getColor(R.color.chart_1));
colors.add(getResources().getColor(R.color.chart_2));
dataSet.setColors(colors);
// format value
dataSet.setValueFormatter(new PieCenterFormatter("分"));
// 指示信息在饼状图外
dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
dataSet.setValueLineColor(Color.BLACK);
PieData pieData = new PieData(dataSet);
pieData.setDrawValues(true); // 需要Value
pieData.setValueTextSize(24); // 字体大小
pieData.setValueTextColor(Color.WHITE);
pieChartView.setData(pieData);
}
4.5 ValueFormatter
formatter的含义是将显示的内容格式化。
我格式化的格式是: 标签+值+单位
public static class PieCenterFormatter extends ValueFormatter {
private final String mUnit;
public PieCenterFormatter(String unit) {
this.mUnit = unit;
}
@Override
public String getPieLabel(float value, PieEntry pieEntry) {
ChartBean bean = (ChartBean) pieEntry.getData();
if (bean != null) {
String unit = TextUtils.isEmpty(mUnit) ? "" : mUnit;
return bean.getLabel() + ":" + bean.getValue() + unit;
}
return "";
}
}
这样一个简单的饼状图就完成了。
4.6 解决问题
- 当数据值为0时怎么在饼状图上显示?
当数据为0时,在饼状图上我们应该显示小部分区域,还是不显示,这首先是咨询产品经理。 什么? 没有产品经理,那就按常规的,给他显示小部分区域,在代码上我们这么实现。
if (bean.getValue() == 0)
strings.add(new PieEntry(0.3f, bean.getLabel(), bean));
- 数据太多时重叠的问题。
这个问题比较复杂,还在该库的生态庞大,有人帮我们解决了这部分问题。
我们自定义一个 MyPieChart,然后使用它。
MyPieChart怎么写,参考:数据重叠解决办法