MPAndroidChart折线图:如何在X轴时间上方显示天气图标?
解决MPAndroidChart在X轴标签上方绘制天气图标问题
当前你通过Entry绑定图标的方式,会让图标跟随温度数值的Y轴位置显示。要实现X轴标签上方显示图标,需自定义X轴渲染器手动绘制图标:
步骤1:移除Entry图标相关代码
先去掉原代码中获取图标但未使用的部分,Entry仅保留时间索引和温度值:
private fun setTempChart(hour: ArrayList<Hour>, id: String) { val entries: MutableList<Entry> = ArrayList() for (i in hour.indices) { entries.add(Entry(i.toFloat(), sharedPreference.temp?.let { hour[i].temp_c.setCurrentTemperature(it).toFloat() }!!)) } val dataSet = LineDataSet(entries, "") dataSet.apply { lineWidth = 0f setDrawCircles(false) setDrawCircleHole(false) isHighlightEnabled = false valueTextColor = Color.WHITE setColors(Color.WHITE) valueTextSize = 12f mode = LineDataSet.Mode.CUBIC_BEZIER setDrawFilled(true) fillColor = Color.WHITE valueTypeface = typeface valueFormatter = object : ValueFormatter() { override fun getFormattedValue(value: Float): String { return String.format(Locale.getDefault(), "%.0f", value) } } } // 后续chart基础配置保留 }
步骤2:自定义X轴渲染器
创建自定义XAxisRenderer,重写drawLabels方法,在绘制完时间标签后,在对应位置上方绘制天气图标:
class CustomXAxisRenderer( viewPortHandler: ViewPortHandler, xAxis: XAxis, transformer: Transformer, private val hourList: ArrayList<Hour>, private val context: Context ) : XAxisRenderer(viewPortHandler, xAxis, transformer) { override fun drawLabels(c: Canvas, pos: Float, anchor: PointF) { super.drawLabels(c, pos, anchor) // 先绘制默认时间标签 val dataSet = mChart?.data?.getDataSetByIndex(0) ?: return val valueToPixelMatrix = mTransformer.valueToPixelMatrix for (i in hourList.indices) { val hourData = hourList[i] // 复用原有图标获取逻辑 val iconDrawable = if (hourData.is_day == 1) { context.setIconDay(hourData.condition.code) } else { context.setIconNight(hourData.condition.code) } ?: continue // 计算X轴对应位置的像素坐标 val xValue = dataSet.entries[i].x val pixelPoint = floatArrayOf(xValue, 0f) valueToPixelMatrix.mapPoints(pixelPoint) // 配置图标大小和位置(可按需调整) val iconSize = 32 val iconX = pixelPoint[0] - iconSize / 2f // 水平居中 val iconY = pos - iconSize - 10f // 在时间标签上方留出间距 // 绘制图标 iconDrawable.setBounds( iconX.toInt(), iconY.toInt(), (iconX + iconSize).toInt(), (iconY + iconSize).toInt() ) iconDrawable.draw(c) } } }
步骤3:给Chart设置自定义渲染器
在chart配置代码中,替换默认的X轴渲染器:
chart.apply { // 原有基础配置(description、坐标轴、legend等)保持不变 data = lineData setVisibleXRange(8f, 8f) animateY(1000) xAxis.apply { setDrawAxisLine(false) textColor = Color.WHITE setDrawGridLines(false) setDrawLabels(true) position = XAxis.XAxisPosition.BOTTOM textSize = 12f valueFormatter = MyAxisFormatter(hour, id) isGranularityEnabled = true granularity = 1f labelCount = entries.size } // 设置自定义X轴渲染器 xAxisRenderer = CustomXAxisRenderer( viewPortHandler, xAxis, transformer, hour, requireActivity() ) }
注意事项
- 确保
setIconDay和setIconNight返回有效的Drawable对象,若返回资源ID,需通过ContextCompat.getDrawable(context, resId)转换。 - 图标大小
iconSize和位置偏移量(iconY中的-10f)可根据UI需求调整,保证图标与时间标签的间距合适。 - 代码已通过
valueToPixelMatrix处理坐标转换,支持图表缩放适配。
内容的提问来源于stack exchange,提问作者Muaz Khan
相关产品推荐
相关产品推荐

