Interface

BringIntoViewSpec

The configuration of how a scrollable reacts to bring into view requests.

FocusScrollingInLazyRowSample

@ExperimentalFoundationApi
@Sampled
@Composable
fun FocusScrollingInLazyRowSample() {
    // a bring into view spec that pivots around the center of the scrollable container
    val customBringIntoViewSpec =
        object : BringIntoViewSpec {
            override fun calculateScrollDistance(
                offset: Float,
                size: Float,
                containerSize: Float,
            ): Float {
                val trailingEdgeOfItemRequestingFocus = offset + size

                val sizeOfItemRequestingFocus = abs(trailingEdgeOfItemRequestingFocus - offset)
                val childSmallerThanParent = sizeOfItemRequestingFocus <= containerSize
                val initialTargetForLeadingEdge =
                    containerSize / 2f - (sizeOfItemRequestingFocus / 2f)
                val spaceAvailableToShowItem = containerSize - initialTargetForLeadingEdge

                val targetForLeadingEdge =
                    if (
                        childSmallerThanParent &&
                            spaceAvailableToShowItem < sizeOfItemRequestingFocus
                    ) {
                        containerSize - sizeOfItemRequestingFocus
                    } else {
                        initialTargetForLeadingEdge
                    }

                return offset - targetForLeadingEdge
            }
        }

    // LocalBringIntoViewSpec will apply to all scrollables in the hierarchy.
    CompositionLocalProvider(LocalBringIntoViewSpec provides customBringIntoViewSpec) {
        LazyRow(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
            items(100) {
                var color by remember { mutableStateOf(Color.White) }
                Box(
                    modifier =
                        Modifier.size(100.dp)
                            .padding(4.dp)
                            .background(Color.Gray)
                            .onFocusChanged { color = if (it.isFocused) Color.Red else Color.White }
                            .border(5.dp, color)
                            .focusable(),
                    contentAlignment = Alignment.Center,
                ) {
                    Text(text = it.toString())
                }
            }
        }
    }
}
Jetpack Compose beyond MaterialFree components, screens and templates for apps that don’t look like Google’s. Copy them into your app, or let your coding agent add them.Browse for free

Content updated: