如何修复MPAndroidChart中Firestore计数的显示错误
MPAndroidChart饼图显示异常问题解决
问题现象
从Firestore数据库获取的计数数据,在MPAndroidChart饼图中显示异常:实际计数为1时图表显示25,计数为3时显示33.33,实际为计数占总数的百分比(如1/4对应25%)。
原代码
private void setPieChart() { pieChart.setDrawHoleEnabled(true); pieChart.setUsePercentValues(true); pieChart.setEntryLabelTextSize(12); pieChart.setEntryLabelColor(Color.BLACK); pieChart.setCenterTextSize(24); pieChart.getDescription().setEnabled(false); Legend l = pieChart.getLegend(); l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT); l.setOrientation(Legend.LegendOrientation.VERTICAL); l.setDrawInside(false); l.setEnabled(true); } private void loadPiechartData() { entries = new ArrayList<>(); db.collection("charot") .whereEqualTo("electricity", "lugi") .count() .get(AggregateSource.SERVER).addOnCompleteListener(task -> { entries.add(new PieEntry(task.getResult().getCount(), "lugi")); db.collection("charot") .whereEqualTo("mahal", "bawi") .count() .get(AggregateSource.SERVER).addOnCompleteListener(task2 -> { entries.add(new PieEntry(task2.getResult().getCount(), "bawi")); db.collection("charot") .whereEqualTo("basta", "ewan") .count() .get(AggregateSource.SERVER).addOnCompleteListener(task3 -> { entries.add(newPieEntry(task2.getResult().getCount(),"ewan")); db.collection("charot") .whereEqualTo("tuiton", "pwede") .count() .get(AggregateSource.SERVER).addOnCompleteListener(task4-> { entries.add(new PieEntry(task4.getResult().getCount(), "pwede")); if (task.isComplete()) { ArrayList<Integer> colors = new ArrayList<>(); for (int color : ColorTemplate.MATERIAL_COLORS) { colors.add(color); } for (int color : ColorTemplate.VORDIPLOM_COLORS) { colors.add(color); } PieDataSet dataSet = new PieDataSet(entries, ""); dataSet.setColors(colors); PieData data = new PieData(dataSet); data.setValueFormatter(new ValueFormatter() { @Override public String getFormattedValue(float value) { return String.valueOf((int) value)} }); data.setDrawValues(true); data.setValueTextSize(12f); data.setValueTextColor(Color.BLACK); pieChart.setData(data); pieChart.invalidate(); pieChart.animateY(1000, Easing.EaseInOutQuad); } }); }); }); });
错误分析
- 核心显示异常原因:
setPieChart()中开启了pieChart.setUsePercentValues(true),该设置会让MPAndroidChart自动将饼图的每个Entry数值转换为占总数的百分比进行渲染,导致实际计数被转换为百分比显示。 - 代码语法错误:
- 第三个饼图Entry创建时,
newPieEntry拼写错误,应为new PieEntry - 第三个查询的结果错误使用了
task2.getResult().getCount(),应该改为task3.getResult().getCount()
- 第三个饼图Entry创建时,
- 逻辑判断问题:仅通过
task.isComplete()判断是否渲染图表,逻辑不准确,应确保所有四个Firestore查询都完成后再进行图表渲染。
修正后的代码
1. 修正饼图基础设置
private void setPieChart() { pieChart.setDrawHoleEnabled(true); // 关闭百分比转换,直接显示原始计数 pieChart.setUsePercentValues(false); pieChart.setEntryLabelTextSize(12); pieChart.setEntryLabelColor(Color.BLACK); pieChart.setCenterTextSize(24); pieChart.getDescription().setEnabled(false); Legend l = pieChart.getLegend(); l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT); l.setOrientation(Legend.LegendOrientation.VERTICAL); l.setDrawInside(false); l.setEnabled(true); }
2. 修正数据加载逻辑
private void loadPiechartData() { entries = new ArrayList<>(); // 使用CountDownLatch确保所有查询完成后再渲染图表 CountDownLatch latch = new CountDownLatch(4); // 第一个查询 db.collection("charot") .whereEqualTo("electricity", "lugi") .count() .get(AggregateSource.SERVER) .addOnCompleteListener(task -> { if (task.isSuccessful()) { entries.add(new PieEntry(task.getResult().getCount(), "lugi")); } latch.countDown(); }); // 第二个查询 db.collection("charot") .whereEqualTo("mahal", "bawi") .count() .get(AggregateSource.SERVER) .addOnCompleteListener(task2 -> { if (task2.isSuccessful()) { entries.add(new PieEntry(task2.getResult().getCount(), "bawi")); } latch.countDown(); }); // 第三个查询(修正数据源和拼写) db.collection("charot") .whereEqualTo("basta", "ewan") .count() .get(AggregateSource.SERVER) .addOnCompleteListener(task3 -> { if (task3.isSuccessful()) { entries.add(new PieEntry(task3.getResult().getCount(), "ewan")); } latch.countDown(); }); // 第四个查询 db.collection("charot") .whereEqualTo("tuiton", "pwede") .count() .get(AggregateSource.SERVER) .addOnCompleteListener(task4 -> { if (task4.isSuccessful()) { entries.add(new PieEntry(task4.getResult().getCount(), "pwede")); } latch.countDown(); }); // 所有查询完成后渲染图表 new Thread(() -> { try { latch.await(); // 切换到主线程更新UI runOnUiThread(() -> { ArrayList<Integer> colors = new ArrayList<>(); for (int color : ColorTemplate.MATERIAL_COLORS) { colors.add(color); } for (int color : ColorTemplate.VORDIPLOM_COLORS) { colors.add(color); } PieDataSet dataSet = new PieDataSet(entries, ""); dataSet.setColors(colors); PieData data = new PieData(dataSet); data.setValueFormatter(new ValueFormatter() { @Override public String getFormattedValue(float value) { return String.valueOf((int) value); } }); data.setDrawValues(true); data.setValueTextSize(12f); data.setValueTextColor(Color.BLACK); pieChart.setData(data); pieChart.invalidate(); pieChart.animateY(1000, Easing.EaseInOutQuad); }); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); }
修正说明
- 关闭
setUsePercentValues(true),让饼图直接使用原始计数数值进行渲染,解决百分比显示问题 - 修复了
newPieEntry拼写错误和第三个查询的数据源错误 - 使用
CountDownLatch替代多层嵌套回调,优化代码可读性,确保所有查询完成后再更新图表,避免数据不全的问题
内容的提问来源于stack exchange,提问作者teachmetocode
相关产品推荐
相关产品推荐

