You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复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);
                                                    }
                                                });
                                    });
                        });
            });

错误分析

  1. 核心显示异常原因:setPieChart()中开启了pieChart.setUsePercentValues(true),该设置会让MPAndroidChart自动将饼图的每个Entry数值转换为占总数的百分比进行渲染,导致实际计数被转换为百分比显示。
  2. 代码语法错误:
    • 第三个饼图Entry创建时,newPieEntry拼写错误,应为new PieEntry
    • 第三个查询的结果错误使用了task2.getResult().getCount(),应该改为task3.getResult().getCount()
  3. 逻辑判断问题:仅通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:40:38