Reputation: 1364
I created a couple of Chip and Chips @Composable functions that I use like this:
Chips {
Chip(text = "Apple")
Chip(text = "Banana")
Chip(text = "Cherry")
}
I'd like the first and last chip to look a bit different. I could do it by using extra arguments to the Chip function:
Chips {
Chip(text = "Apple", isFirst = true)
Chip(text = "Banana")
Chip(text = "Cherry", isLast = true)
}
It is a bit cumbersome. How can I make an individual Chip aware of its siblings.
Similarly we might want to change the color of the Chips depending on whether there are Chips inside or not.
Chips(chipCount = if (addCherry) 3 else 2) {
Chip(text = "Apple")
Chip(text = "Banana")
if (addCherry) Chip(text = "Cherry")
}
How would I do that more elegantly.
Upvotes: 1
Views: 606
Reputation: 2376
I would send array of chip data into Chips
composable and then use a loop to add Chip
composables.
@Composable
fun Chips(
chips: List<ChipData>
) {
chips.forEachIndexed { index, chip ->
Chip(
text = chip.text,
isFirst = index == 0,
isLast = index == chips.lastIndex,
)
}
}
Similarly, you can change the colour of Chips
based on the size of the list of Chip
objects.
If you want to pass multiple completely different composables, slotting might as well save you (this is how toolbars and such are done). Instead of an object, you send in a composable, which can then be anything you want (the same was a Button
is also done). Here is an example of it:
@Composable
fun ListOfComposables() {
val comps = listOf<@Composable (isFirst: Boolean, isLast: Boolean) -> Unit>(
{ isFirst, isLast -> Chip(text = "first chip", isFirst = isFirst, isLast = isLast) },
{ isFirst, isLast -> Chip(text = "chip2", isFirst = isFirst, isLast = isLast) },
{ _, _ ->
Button(onClick = { }) {
Text(text = "Button")
}
},
{ isFirst, isLast -> Chip(text = "Chip3", isFirst = isFirst, isLast = isLast) },
{ _, _ -> Text(text = "Random text") },
{ isFirst, isLast -> Chip(text = "last chip", isFirst = isFirst, isLast = isLast) }
)
Column {
comps.forEachIndexed { index, function ->
function(
isFirst = index == 0,
isLast = index == comps.lastIndex
)
}
}
}
@Composable
fun Chip(
text: String,
isFirst: Boolean = false,
isLast: Boolean = false
) {
Text(
text = text,
color = when {
isFirst -> Color.Green
isLast -> Color.Red
else -> Color.Unspecified
},
modifier = Modifier
.background(Color.LightGray),
)
}
The preview of this code looks like this: .
Code is quite ugly, but it gets the point across, I hope.
Upvotes: 2
Reputation: 1370
I would pass the list in the Chips
composable, but I will add to the ChipData the uiInfo (a sealed Class or an enum) and then inside the forEach
loop I would do a when.
Something like this:
enum class UIInfo {
FILTER, INVERSE, NORMAL
}
data class ChipData(
val text: String,
val uiInfo: UIInfo,
)
@Composable
fun Chips(
chips: List<ChipData>
) {
chips.forEach { chip ->
Chip(
text = chip.text,
uiInfo = chip.uiInfo,
)
}
}
Upvotes: 0