@@ -8,7 +8,6 @@ import androidx.compose.animation.core.LinearEasing
88import androidx.compose.animation.core.tween
99import androidx.compose.foundation.Indication
1010import androidx.compose.foundation.background
11- import androidx.compose.foundation.clickable
1211import androidx.compose.foundation.interaction.MutableInteractionSource
1312import androidx.compose.foundation.layout.Arrangement
1413import androidx.compose.foundation.layout.Box
@@ -24,6 +23,7 @@ import androidx.compose.foundation.lazy.LazyListState
2423import androidx.compose.foundation.lazy.LazyRow
2524import androidx.compose.foundation.lazy.itemsIndexed
2625import androidx.compose.foundation.lazy.rememberLazyListState
26+ import androidx.compose.foundation.selection.selectable
2727import androidx.compose.runtime.Composable
2828import androidx.compose.runtime.Immutable
2929import androidx.compose.runtime.LaunchedEffect
@@ -38,9 +38,11 @@ import androidx.compose.ui.Alignment
3838import androidx.compose.ui.Modifier
3939import androidx.compose.ui.graphics.Color
4040import androidx.compose.ui.platform.LocalDensity
41+ import androidx.compose.ui.semantics.CollectionInfo
42+ import androidx.compose.ui.semantics.CollectionItemInfo
4143import androidx.compose.ui.semantics.Role
42- import androidx.compose.ui.semantics.role
43- import androidx.compose.ui.semantics.selected
44+ import androidx.compose.ui.semantics.collectionInfo
45+ import androidx.compose.ui.semantics.collectionItemInfo
4446import androidx.compose.ui.semantics.semantics
4547import androidx.compose.ui.text.font.FontWeight
4648import androidx.compose.ui.text.style.TextOverflow
@@ -154,14 +156,18 @@ fun TabRow(
154156 LazyRow (
155157 state = config.listState,
156158 modifier = Modifier
157- .fillMaxSize(),
159+ .fillMaxSize()
160+ // Announce "tab X of Y": this explicit count overrides LazyRow's auto-derived
161+ // collectionInfo (the leftmost semantics in the chain wins the property).
162+ .semantics { collectionInfo = CollectionInfo (rowCount = 1 , columnCount = tabs.size) },
158163 verticalAlignment = Alignment .CenterVertically ,
159164 horizontalArrangement = Arrangement .spacedBy(itemSpacing),
160165 overscrollEffect = null ,
161166 ) {
162167 itemsIndexed(tabs) { index, tabText ->
163168 TabItem (
164169 text = tabText,
170+ index = index,
165171 isSelected = selectedTabIndex == index,
166172 onClick = { currentOnTabSelected.invoke(index) },
167173 cornerRadius = config.cornerRadius,
@@ -284,14 +290,18 @@ fun TabRowWithContour(
284290 LazyRow (
285291 state = config.listState,
286292 modifier = Modifier
287- .fillMaxSize(),
293+ .fillMaxSize()
294+ // Announce "tab X of Y": this explicit count overrides LazyRow's auto-derived
295+ // collectionInfo (the leftmost semantics in the chain wins the property).
296+ .semantics { collectionInfo = CollectionInfo (rowCount = 1 , columnCount = tabs.size) },
288297 verticalAlignment = Alignment .CenterVertically ,
289298 horizontalArrangement = Arrangement .spacedBy(itemSpacing),
290299 overscrollEffect = null ,
291300 ) {
292301 itemsIndexed(tabs) { index, tabText ->
293302 TabItemWithContour (
294303 text = tabText,
304+ index = index,
295305 isSelected = selectedTabIndex == index,
296306 onClick = { currentOnTabSelected.invoke(index) },
297307 cornerRadius = config.cornerRadius,
@@ -310,6 +320,7 @@ fun TabRowWithContour(
310320@Composable
311321private fun TabItem (
312322 text : String ,
323+ index : Int ,
313324 isSelected : Boolean ,
314325 onClick : () -> Unit ,
315326 cornerRadius : Dp ,
@@ -324,14 +335,20 @@ private fun TabItem(
324335 .fillMaxHeight()
325336 .width(width)
326337 .squircleClip(cornerRadius)
327- .clickable(
338+ .selectable(
339+ selected = isSelected,
340+ onClick = onClick,
341+ role = Role .Tab ,
328342 interactionSource = interactionSource,
329343 indication = indication,
330- onClick = onClick,
331344 )
332345 .semantics {
333- role = Role .Tab
334- selected = isSelected
346+ collectionItemInfo = CollectionItemInfo (
347+ rowIndex = 0 ,
348+ rowSpan = 1 ,
349+ columnIndex = index,
350+ columnSpan = 1 ,
351+ )
335352 }
336353 .padding(horizontal = 12 .dp),
337354 contentAlignment = contentAlignment,
@@ -350,6 +367,7 @@ private fun TabItem(
350367@Composable
351368private fun TabItemWithContour (
352369 text : String ,
370+ index : Int ,
353371 isSelected : Boolean ,
354372 onClick : () -> Unit ,
355373 cornerRadius : Dp ,
@@ -364,14 +382,20 @@ private fun TabItemWithContour(
364382 .fillMaxHeight()
365383 .width(width)
366384 .squircleClip(cornerRadius)
367- .clickable(
385+ .selectable(
386+ selected = isSelected,
387+ onClick = onClick,
388+ role = Role .Tab ,
368389 interactionSource = interactionSource,
369390 indication = indication,
370- onClick = onClick,
371391 )
372392 .semantics {
373- role = Role .Tab
374- selected = isSelected
393+ collectionItemInfo = CollectionItemInfo (
394+ rowIndex = 0 ,
395+ rowSpan = 1 ,
396+ columnIndex = index,
397+ columnSpan = 1 ,
398+ )
375399 },
376400 contentAlignment = contentAlignment,
377401 ) {
@@ -392,7 +416,7 @@ private fun TabItemWithContour(
392416private data class TabRowConfig (
393417 val tabWidth : Dp ,
394418 val cornerRadius : Dp ,
395- val listState : androidx.compose.foundation.lazy. LazyListState ,
419+ val listState : LazyListState ,
396420)
397421
398422/* *
0 commit comments