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

如何在MPAndroidChart中访问单个柱状图条目(适配无障碍需求)

解决MPAndroidChart柱状图单个条目无障碍焦点支持问题

核心原因

MPAndroidChart的柱状条目并非独立View,而是通过Canvas绘制的图形,默认没有独立焦点和视图ID,所以布局检查器里看不到单独条目,也无法直接让单个条目获取焦点。

实现方案

1. 自定义图表处理焦点切换

重写BarChart的按键事件方法,手动管理焦点在条目间的切换,并添加焦点高亮绘制:

class AccessibleBarChart(context: Context, attrs: AttributeSet?) : BarChart(context, attrs) {
    private var focusedBarIndex = -1

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        val barData = data?.getDataSetByIndex(0) as? BarDataSet ?: return super.onKeyDown(keyCode, event)
        val entryCount = barData.entryCount

        when (keyCode) {
            KeyEvent.KEYCODE_DPAD_RIGHT -> {
                if (focusedBarIndex < entryCount - 1) {
                    focusedBarIndex++
                    invalidate()
                    announceForAccessibility("当前条目数值:${barData.getEntryForIndex(focusedBarIndex).y}")
                    return true
                }
            }
            KeyEvent.KEYCODE_DPAD_LEFT -> {
                if (focusedBarIndex > 0) {
                    focusedBarIndex--
                    invalidate()
                    announceForAccessibility("当前条目数值:${barData.getEntryForIndex(focusedBarIndex).y}")
                    return true
                }
            }
        }
        return super.onKeyDown(keyCode, event)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        // 绘制焦点高亮边框
        if (focusedBarIndex != -1) {
            val entry = data?.getDataSetByIndex(0)?.getEntryForIndex(focusedBarIndex) ?: return
            val barRect = getBarBounds(entry)
            val highlightPaint = Paint().apply {
                color = Color.parseColor("#E53935")
                style = Paint.Style.STROKE
                strokeWidth = 4f
            }
            canvas?.drawRect(barRect, highlightPaint)
        }
    }
}

2. 添加无障碍代理支持

为自定义图表绑定无障碍代理,让屏幕阅读器识别可操作的条目集合:

barChart.accessibilityDelegate = object : View.AccessibilityDelegate() {
    override fun onInitializeAccessibilityNodeInfo(host: View?, info: AccessibilityNodeInfo?) {
        super.onInitializeAccessibilityNodeInfo(host, info)
        info?.apply {
            className = AccessibleBarChart::class.java.name
            isFocusable = true
            addAction(AccessibilityNodeInfo.ACTION_FOCUS)
            addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)
            addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)
        }
    }
}

3. 替换布局中的图表控件

将XML里的默认BarChart替换为自定义的AccessibleBarChart:

<com.yourpackage.AccessibleBarChart
    android:id="@+id/barChart"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusable="true" />

关键注意事项

  • 无法给单个绘制的条目设置独立视图ID,只能通过索引区分条目
  • 自定义高亮绘制时,需注意和原有图表的高亮逻辑兼容
  • 无障碍播报内容可根据需求扩展,比如增加条目名称、分类信息等

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:42:15