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

Android中MPAndroidChart饼图图标过大如何调整?setBounds无效

MPAndroidChart饼图图标过大,setBounds()不生效的解决办法

我在Android应用中使用MPAndroidChart的饼图(PieChart)时,遇到图标显示过大的问题,尝试用pic.setBounds()方法缩小图标但没有效果。相关代码如下:

fun updatePieChart(list: List<BudgetItem>, pieChart: PieChart, context: Context) {
        var expenses = 0F
        val expenseEntry: ArrayList<PieEntry> = ArrayList()
        val categories = list.groupBy { it.category.name }

        for (cats in categories) {
            var pic = ContextCompat.getDrawable(context, R.drawable.incomes_money_48)
            for (i in cats.value) {
                expenses += i.cost
                pic = ContextCompat.getDrawable(context, i.category.pic)
            }
            pic?.setTint(ContextCompat.getColor(context, R.color.secondary_text))
            pic?.setBounds(0,0,20,20)

            expenseEntry.add(PieEntry(expenses, cats.key, pic))
            Log.i("CatPic", "$pic")
        }
        val pieDataSet = PieDataSet(expenseEntry,"")

        pieDataSet.setColors(ColorTemplate.COLORFUL_COLORS, 100)
        var pieData = PieData(pieDataSet)
        pieChart.setData(pieData)
        pieChart.legend.formSize = 12f
        pieChart.setDrawEntryLabels(false)
        pieChart.setEntryLabelColor(R.color.accent_orange)
        pieChart.data.setValueTextSize(14f)
        pieChart.legend.textSize = 14f
        pieChart.description.isEnabled = false
        pieChart.centerText = "Расходы"
        pieChart.invalidate()
    }

饼图效果截图:
饼图截图


解决方法

MPAndroidChart的PieDataSet默认会忽略你给Drawable设置的bounds,需要通过库提供的API或者自定义Renderer来调整图标大小。

方法1:统一设置所有图标尺寸(最简单)

在初始化PieDataSet后,直接调用iconSize属性设置图标大小,单位是像素:

// 直接设置像素值,比如20px
pieDataSet.iconSize = 20f

// 适配不同屏幕,建议转dp为像素
fun dpToPx(dp: Float, context: Context): Float {
    return dp * context.resources.displayMetrics.density
}
// 使用示例:设置20dp的图标大小
pieDataSet.iconSize = dpToPx(20f, context)

方法2:自定义Renderer实现不同图标尺寸(按需使用)

如果需要给不同的饼图条目设置不同大小的图标,需要自定义PieChartRenderer,重写drawExtras()方法来手动控制每个图标的绘制边界:

class CustomPieRenderer(
    chart: PieChart,
    animator: ChartAnimator,
    viewPortHandler: ViewPortHandler
) : PieChartRenderer(chart, animator, viewPortHandler) {

    override fun drawExtras(canvas: Canvas) {
        super.drawExtras(canvas)
        val data = mChart.data ?: return
        val dataSets = data.dataSets

        for (dataSet in dataSets) {
            val pieDataSet = dataSet as PieDataSet
            if (!pieDataSet.isDrawIconsEnabled) continue

            val entries = pieDataSet.entries
            val drawAngles = mChart.drawAngles
            val rotationAngle = mChart.rotationAngle
            val radius = mChart.radius - mChart.legendRadius
            val center = mChart.centerCircleBox
            var currentRotation = rotationAngle

            for (index in entries.indices) {
                val entry = entries[index] as PieEntry
                val drawable = entry.icon ?: continue

                // 计算图标位置
                currentRotation += drawAngles[index] / 2f
                val x = (center.x + radius * Math.cos(Math.toRadians(currentRotation.toDouble()))).toFloat()
                val y = (center.y + radius * Math.sin(Math.toRadians(currentRotation.toDouble()))).toFloat()

                // 这里设置当前图标的大小,可根据entry自定义
                val iconSize = dpToPx(20f, mChart.context)
                drawable.setBounds(
                    (x - iconSize / 2).toInt(),
                    (y - iconSize / 2).toInt(),
                    (x + iconSize / 2).toInt(),
                    (y + iconSize / 2).toInt()
                )
                drawable.draw(canvas)

                currentRotation += drawAngles[index] / 2f
            }
        }
    }

    private fun dpToPx(dp: Float, context: Context): Float {
        return dp * context.resources.displayMetrics.density
    }
}

然后给PieChart设置这个自定义Renderer:

pieChart.renderer = CustomPieRenderer(pieChart, pieChart.animator, pieChart.viewPortHandler)

为什么setBounds()无效?

MPAndroidChart在绘制饼图图标时,会自动重新计算图标的位置和尺寸,覆盖你之前给Drawable设置的bounds。默认逻辑是使用PieDataSet.iconSize作为图标大小,所以直接设置这个属性是最有效的方式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:45:32