1

I have a column which consists of multiple composables of one Text (For row title) and one lazyrow (For row items), for TV screens

For reference :

Column {
    AlignedRow(data)
}

fun AlignedRow(data) {
    if (data != null)
    Column {
        Text()
        LazyRow {
            items(data.rowList) {
                //add items
            }
        }
    }

While scrolling the parent column downwards, everything is as expected; but while scrolling back up, the top most AlignedRow only focusses on one of the child items at the top of the screen and thus the title text is left out of the screen?

How can I make this scroll work in a way so that when we scroll up both the lazyrow and the title text is rendered onto the screen? Any help would be appreciated!

vighnesh153
  • 4,354
  • 2
  • 13
  • 27
Rahul Rawat
  • 103
  • 6

2 Answers2

1

You can create a extension method on Modifier which will bring the entire item in view if any of its children is focused.

internal fun Modifier.bringIntoViewIfChildrenAreFocused(): Modifier = composed(
    inspectorInfo = debugInspectorInfo { name = "bringIntoViewIfChildrenAreFocused" },
    factory = {
        var myRect: Rect = Rect.Zero
        this
            .onSizeChanged {
                myRect = Rect(Offset.Zero, Offset(it.width.toFloat(), it.height.toFloat()))
            }
            .bringIntoViewResponder(
                remember {
                    object : BringIntoViewResponder {
                        // return the current rectangle and ignoring the child rectangle received.
                        @ExperimentalFoundationApi
                        override fun calculateRectForParent(localRect: Rect): Rect = myRect

                        // The container is not expected to be scrollable. Hence the child is
                        // already in view with respect to the container.
                        @ExperimentalFoundationApi
                        override suspend fun bringChildIntoView(localRect: () -> Rect?) {}
                    }
                }
            )
    }
)

Here is how you can use it:

Column {
    AlignedRow(data)
}

fun AlignedRow(data) {
    if (data != null)

    Column(Modifier.bringIntoViewIfChildrenAreFocused()) {
        Text()
        LazyRow {
            items(data.rowList) {
                //add items
            }
        }
    }
}

Reference from the official Compose for TV library

vighnesh153
  • 4,354
  • 2
  • 13
  • 27
0

You can put the Text composable inside the LazyRow

LazyRow {
    item {
        Text()
    }
    items(data.rowList) {
        ...
    }
}

Merig
  • 1,751
  • 2
  • 13
  • 18
  • 1
    But wouldn't this put the text alongside all the other items in the row, I want it to be something like Text above and all the row items below it – Rahul Rawat Mar 13 '23 at 12:04