Compose ConstraintLayout Scrolling

202 Views Asked by At

Hey guy's im working on porting my Android TV app to Compose. The only issue i have is the EPG guide..There is not much info on this yet.

I got a good idea but need help with this..

Top Hours scroll is done

Side channels Vertical scroll is done

The issue is the Events(programs)

i got one row done that has horizontalScroll ,but i need that row to be duplicated for each channel and that has a verticalScroll when channel is scrolling up or down.

Also since its TV , i added focusable(true) but i dont see the highlight when on the item?

enter image description here

private val HOURS_S = listOf("1:00", "2:00", "3:00", "4:00","5:00", "6:00","7:00","8:00",   "9:00","10:00","11:00","12:00","13:00","14:00","15:00""16:00","17:00","18:00","19:00",
"20:00","21:00","22:00","23:00","24:00")

@Composable
fun ConstraintLayoutEpg(
    modifier: Modifier = Modifier,
    num: Int,
){
    val verticalScrollState = rememberScrollState()
    val horizontalScrollState = rememberScrollState()
    ConstraintLayout {
        val (hours,channel,event) = createRefs()

        BasicHourHeader(HOURS_S,modifier = Modifier.constrainAs(hours){
            top.linkTo(parent.top, margin = 16.dp)
        })

        Column( modifier.border(2.dp, Color.White).verticalScroll(verticalScrollState).focusable(true).constrainAs(channel){
            top.linkTo(hours.bottom, margin = 6.dp)
        }) {
            repeat(num) { i ->
                Text(
                    text = "Channel $i", color = Color.White, modifier = Modifier
                        .padding(8.dp)
                        .padding(8.dp)
                        .focusable(true)
                )
            }
        }
            Row(
                modifier = modifier.border(2.dp, Color.White).horizontalScroll(horizontalScrollState).focusable(true)
                    .constrainAs(event) {
                        start.linkTo(channel.end, margin = 6.dp)
                        top.linkTo(hours.bottom, margin = 6.dp)
                    }) {
                repeat(20) { i ->
                    Text(
                        text = "Channel Prg $i", color = Color.White, modifier = Modifier
                            .padding(10.dp)
                            .padding(8.dp)
                            .width(256.dp)
                            .focusable(true),textAlign = TextAlign.Start,
                    )
               }
            }

    }
}
1

There are 1 best solutions below

3
On

You need to put your Row inside another Column which will also repeat n times:

Column(modifier = Modifier.verticalScroll(verticalScrollState).constrainAs(event) {
        start.linkTo(channel.end, margin = 6.dp)
        top.linkTo(hours.bottom, margin = 6.dp)
    }) {
        repeat(num) {
            Row(
                modifier = modifier
                    .border(2.dp, Color.White)
                    .horizontalScroll(rememberScrollState())
                    .focusable(true)) {
                repeat(20) { i ->
                    Text(
                        text = "Channel Prg $i", color = Color.White, modifier = Modifier
                            .padding(10.dp)
                            .padding(8.dp)
                            .width(256.dp)
                            .focusable(true),textAlign = TextAlign.Start,
                    )
                }
            }
        }
    }

I don't know what the performance of this would be though if you have hundreds of items. Also, I'd be concerned on how it looks and if the texts would be aligned in all devices. So perhaps use a fix height for every channel child.