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

MPAndroidChart组合图:BarChart复选框控制显隐触发空指针异常

解决MPAndroidChart组合图切换Bar复选框时的NullPointerException问题

我看了你的代码和异常信息,问题的根源很明确:当你取消Bar复选框时,CombinedData中没有设置BarData(或者说BarData为null),但CombinedChart的渲染器仍然会尝试初始化BarChart的缓冲区,这时候访问null的BarData就会抛出空指针异常。

MPAndroidChart的CombinedChartRenderer会初始化所有类型的渲染器(Bar、Line等),不管你有没有对应的数据。当BarData为null时,BarChartRenderer.initBuffers()方法里调用barData.getDataSetCount()就会触发NullPointerException。

下面是具体的修复步骤:

1. 修改setChartData()方法,避免BarData/LineData为null

当不需要显示某类图表时,不要让对应的数据为null,而是设置一个空的数据集。这样渲染器不会因为null而崩溃,同时也不会绘制任何内容:

public void setChartData() {
    CombinedData chartData = new CombinedData();
    
    // 处理Bar数据:勾选时用真实数据,否则用空的BarData
    if (chechabc.isChecked()) {
        chartData.setData(barData);
    } else {
        chartData.setData(new BarData());
    }
    
    // 处理Line数据:勾选时用真实数据,否则用空的LineData
    if (chechmnb.isChecked()) {
        chartData.setData(lineData);
    } else {
        chartData.setData(new LineData());
    }

    // 确保x轴最大值正确(当有数据时)
    if (chartData.getXMax() > 0) {
        xAxis.setAxisMaximum(chartData.getXMax() + 0.25f);
    }
    mChart.setData(chartData);
    mChart.notifyDataSetChanged();
    mChart.invalidate();
}

2. 修复复选框监听器的递归调用问题

你的复选框监听器里,当取消勾选时如果另一个也没勾选,会强制设置为true,这会触发onCheckedChanged的递归调用,可能导致不必要的setChartData()执行。我们可以先移除监听器,设置状态后再重新添加:

修改Bar复选框的监听器

chechabc.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
        // 只处理用户手动触发的操作,避免递归
        if (!compoundButton.isPressed()) {
            return;
        }
        
        if (!b) {
            if (!chechmnb.isChecked()) {
                // 临时移除监听器,避免递归触发
                chechabc.setOnCheckedChangeListener(null);
                chechabc.setChecked(true);
                // 重新添加监听器
                chechabc.setOnCheckedChangeListener(this);
                return;
            }
        }
        setChartData();
    }
});

修改Line复选框的监听器

chechmnb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
        if (!compoundButton.isPressed()) {
            return;
        }
        
        if (!b) {
            if (!chechabc.isChecked()) {
                chechmnb.setOnCheckedChangeListener(null);
                chechmnb.setChecked(true);
                chechmnb.setOnCheckedChangeListener(this);
                return;
            }
        }
        setChartData();
    }
});

3. 对齐折线图和柱状图的X轴数据(可选但推荐)

你的折线图数据X值是index + 0.5f(0.5到11.5),但柱状图的X值是1到9,这会导致X轴显示和数据位置不对齐。修改getBarEnteries()方法,让柱状图的X值和折线图一致:

private ArrayList<BarEntry> getBarEnteries(ArrayList<BarEntry> entries) {
    // 对应12个月份,X值和折线图对齐(0.5到11.5)
    entries.add(new BarEntry(0.5f, 20));
    entries.add(new BarEntry(1.5f, 10));
    entries.add(new BarEntry(2.5f, 80));
    entries.add(new BarEntry(3.5f, 40));
    entries.add(new BarEntry(4.5f, 20));
    entries.add(new BarEntry(5.5f, 60));
    entries.add(new BarEntry(6.5f, 22));
    entries.add(new BarEntry(7.5f, 15));
    entries.add(new BarEntry(8.5f, 45));
    // 补充剩下3个月份的数据,保持X轴范围一致
    entries.add(new BarEntry(9.5f, 0));
    entries.add(new BarEntry(10.5f, 0));
    entries.add(new BarEntry(11.5f, 0));
    return entries;
}

测试验证

做完这些修改后,你可以:

  • 勾选/取消Line复选框,折线图正常显示/隐藏
  • 勾选/取消Bar复选框,柱状图正常显示/隐藏,不会再出现NullPointerException
  • 确保至少有一个复选框被勾选,符合你的业务逻辑

内容的提问来源于stack exchange,提问作者Shree

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:58:31