How can I extract items from LazyColumn in Android Jetpack Compose?

230 Views Asked by At

The following is an overly simplified version of my case. Since I am under NDA, I can't post the actual code.

LazyColumn {
    //  ----- block 1 -----
    item {
        Text(text = "header 1")
    }
    items(names) { name ->
        Text(text = name)
    }
    item {
        Button(onClick = onClick) {
            Text("Button 1")
        }
    }
    //  -------------------

    //  ----- block 2 -----
    item {
        Text(text = "Header 2")
    }
    item {
        Button(onClick = onClick) {
            Text("Button 2")
        }
    }
    //  -------------------
}

In reality block 1 and block 2 are way more complex than that, but in principle similar enough. Block 1 has the infinite list of objects plus another few hard coded ones; block 2 has only hard coded items. I would like to extract them both (but especially block 1) somehow such that I can simplify my component and have an easier time with screenshot testing (block 1 has a number different conditional items in it). Is there any way of having all those item {} and items(){} in a function without a LazyColumn wrapping around them? Such that I could pass that inside the LazyColumn above.

I tried having the LazyColumn only around my infinite list of items and everything inside a Column but that didn't work well with scrolling (and I'm not sure how performance friendly that is). But if I'm wrong please let me know!

2

There are 2 best solutions below

2
On BEST ANSWER

Perhaps this meets your needs

@Composable
fun LazySample() {
    LazyColumn {
        CustomSampleOne()
        CustomSampleTwo()
    }
}


fun LazyListScope.CustomSampleOne() {
    //  ----- block 1 -----
    item {
        Text(text = "header 1")
    }
    items(names) { name ->
        Text(text = name)
    }
    item {
        Button(onClick = onClick) {
            Text("Button 1")
        }
    }
    //  -------------------
}

fun LazyListScope.CustomSampleTwo() {
    //  ----- block 2 -----
    item {
        Text(text = "Header 2")
    }
    item {
        Button(onClick = { }) {
            Text("Button 2")
        }
    }
    //  -------------------
}
0
On

You can use Kotlin Extension Function to achieve that.

We have created an Extension Function on LazyListScope and then we are using it as Item in LazyColumn

Here is an example.

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LazyColumnExtExample() {
    Scaffold(topBar = {
        TopAppBar(title = { Text(text = "Example") })
    }) {
        LazyColumn(
            modifier = Modifier
                .fillMaxSize()
                .padding(it)
        ) {
            Item1()
            Item2()
        }
    }
}

fun LazyListScope.Item1() {
    item {
        Text(text = "First Item")
    }
}

fun LazyListScope.Item2() {
    item {
        //You can put any  content here
    }
}