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
相关产品推荐
相关产品推荐

