为FlowRow的RadioButton配置无障碍语义:如何正确设置CollectionInfo?
不需要自定义FlowRow,通过Compose的语义API结合状态就能实现需求,以下是具体方案:
核心思路
无障碍读屏对集合信息的核心需求是总项数和当前项的位置,FlowRow的动态行列数并非必需——多数场景下,读屏只需告知用户“共X项,当前是第Y项”即可。若确实需要精确行列信息,也可通过布局监听实现,无需自定义组件。
基础实现(满足“共X项”需求)
直接利用总项数配置CollectionInfo和CollectionItemInfo,无需计算动态行列:
val totalItems = 5 val selected by remember { mutableStateOf(0) } FlowRow( modifier = Modifier .selectableGroup() .semantics { // 配置集合总信息:总项数5,布局类型设为网格(对应FlowRow的流式布局) collectionInfo = CollectionInfo( size = totalItems, layoutType = CollectionLayoutType.Grid ) } ) { repeat(totalItems) { index -> RadioButton( selected = selected == index, onClick = { selected = index }, modifier = Modifier.semantics { // 配置当前项的集合位置信息:索引、总项数 collectionItemInfo = CollectionItemInfo( index = index, size = totalItems ) } ) } }
此时读屏会播报类似“共5项的网格,第1项”“已选中,共5项的网格,第3项”的内容,满足基础需求。
进阶实现(获取动态行列数)
若需要读屏播报行列位置(如“第2行第1列,共2行3列”),可通过onGloballyPositioned监听布局尺寸计算行列:
val totalItems = 5 val selected by remember { mutableStateOf(0) } val flowRowWidth = remember { mutableStateOf(0) } val itemWidth = remember { mutableStateOf(0) } val columnCount by remember { derivedStateOf { if (flowRowWidth.value > 0 && itemWidth.value > 0) { (flowRowWidth.value / itemWidth.value).coerceAtLeast(1) } else 1 } } val rowCount by remember { derivedStateOf { (totalItems + columnCount - 1) / columnCount // 向上取整计算行数 } } FlowRow( modifier = Modifier .selectableGroup() .onGloballyPositioned { coordinates -> flowRowWidth.value = coordinates.size.width } .semantics { collectionInfo = CollectionInfo( size = totalItems, layoutType = CollectionLayoutType.Grid, rowCount = rowCount, columnCount = columnCount ) } ) { repeat(totalItems) { index -> RadioButton( selected = selected == index, onClick = { selected = index }, modifier = Modifier .onGloballyPositioned { coordinates -> // 仅保存第一个item的宽度(假设所有item尺寸一致) if (index == 0) { itemWidth.value = coordinates.size.width } } .semantics { collectionItemInfo = CollectionItemInfo( index = index, size = totalItems, rowIndex = index / columnCount, columnIndex = index % columnCount ) } ) } }
说明:
- 通过
onGloballyPositioned获取FlowRow总宽度和单个RadioButton的宽度,计算每行可容纳的列数 - 用
derivedStateOf实时计算行列数,确保布局变化时自动更新 - 每个item的行列索引通过
index / columnCount和index % columnCount计算
内容的提问来源于stack exchange,提问作者coding4mobile
相关产品推荐
相关产品推荐

