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

MPAndroidChart堆叠柱状图刷新后增选币种崩溃问题排查

Android MPAndroidChart 堆叠柱状图刷新崩溃问题修复

问题概述

开发的Android应用使用MPAndroidChart展示堆叠柱状图,集成SwipeRefreshLayout后出现崩溃:首次选择X种币种正常展示,刷新后选择X+1种币种时触发IndexOutOfBoundsException,崩溃点指向图例渲染逻辑。

崩溃根源分析

从堆栈信息和代码来看,崩溃由以下几个问题共同导致:

  1. 全局数据未清空:myChartData作为全局可变列表,每次API调用成功后直接追加数据,未清空旧数据,导致新旧数据混合,且不同批次BarEntry的values数组长度(对应币种数量)不一致,触发图表内部逻辑错误。
  2. 方法参数误用:prepareChart方法接收entries参数,但创建BarDataSet时错误使用了未定义的全局变量(推测为笔误的myEntries),导致DataSet绑定旧数据,与新的币种数量不匹配。
  3. 颜色列表生成缺陷:生成colorsList时,若随机颜色重复则跳过添加,导致colorsList长度可能小于pickedCurrs的长度,后续创建LegendEntry时访问colorsList[i]触发数组越界。
  4. X轴格式化器参数错误:设置X轴格式化器时使用全局变量myXAxisValues,而非方法传入的xAxisValues,导致X轴标签与当前数据不匹配。

修复步骤

1. 清空全局数据,避免累积

在API成功回调开始时,清空myChartData,确保每次使用全新数据:

is MyWrapper.Success -> {
    myChartData.clear() // 新增:清空旧数据
    status.data?.timeSeriesRates?.entries?.forEachIndexed { index, entry ->
        myChartData.add(
            BarEntry(
                index.toFloat(),
                entry.value.values.map { it.toFloat() }.toFloatArray()
            )
        )
    }
    makeChart(
        myChartData,
        formatDate(status.data?.timeSeriesRates?.keys!!.toList()),
        mSelectedCurrencies
    )
}

2. 修正DataSet的数据源参数

在prepareChart中,使用方法参数entries创建BarDataSet,而非错误的全局变量:

// 原错误代码
// set = BarDataSet(myEntries, "x")
// 修改为
set = BarDataSet(entries, "x")

3. 修复颜色列表生成逻辑

确保colorsList长度与币种数量一致,可通过循环生成不重复颜色,或允许颜色重复(根据业务需求选择):

方案一:生成不重复颜色

val colorsList = mutableListOf<Int>()
for (i in pickedCurrs.indices) {
    var color: Int
    do {
        color = Color.argb(
            255,
            Random().nextInt(256),
            Random().nextInt(256),
            Random().nextInt(256)
        )
    } while (colorsList.contains(color)) // 循环直到生成唯一颜色
    colorsList.add(color)
}

方案二:允许颜色重复(简化逻辑)

val colorsList = mutableListOf<Int>()
for (i in pickedCurrs.indices) {
    val color = Color.argb(
        255,
        Random().nextInt(256),
        Random().nextInt(256),
        Random().nextInt(256)
    )
    colorsList.add(color) // 直接添加,不判断重复
}

4. 修正X轴格式化器参数

使用方法传入的xAxisValues设置X轴格式化器:

// 原错误代码
// mBinding.timeSeriesChart.xAxis?.valueFormatter = IndexAxisValueFormatter(myXAxisValues)
// 修改为
mBinding.timeSeriesChart.xAxis?.valueFormatter = IndexAxisValueFormatter(xAxisValues)

5. 可选:清空图表旧状态(增强稳定性)

在prepareChart方法开头,清空图表的旧数据和状态,避免残留:

private fun prepareChart(
    entries: MutableList<BarEntry>,
    xAxisValues: ArrayList<String>,
    pickedCurrs: MutableList<String>
) {
    mBinding.timeSeriesChart.clear() // 新增:清空旧图表状态
    val colorsList = mutableListOf<Int>()
    // 后续代码不变
}

验证修复

完成上述修改后,测试以下场景:

  • 首次选择X种币种,确认图表正常显示
  • 刷新后选择X+1种币种,确认应用不崩溃,图表数据和图例正常展示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:54:51