Skip to content

Instantly share code, notes, and snippets.

@bmc08gt

bmc08gt/Grid.kt

Last active Jan 10, 2021
Embed
What would you like to do?
Jetpack Compose dynamic grid
import androidx.compose.foundation.Box
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.key
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@Composable
fun <T>Grid(
contentPadding: InnerPadding = InnerPadding(0.dp),
mainAxisSpacing: Dp = 0.dp,
crossAxisSpacing: Dp = 0.dp,
columns: Int = 2,
items: List<T>,
child: @Composable (item: T, innerPadding: InnerPadding, weight: Float) -> Unit
) {
Box(modifier = Modifier.padding(contentPadding)) {
val mainAxisPadding = InnerPadding(start = mainAxisSpacing, end = mainAxisSpacing)
val crossAxisPadding =
InnerPadding(start = crossAxisSpacing / columns, end = crossAxisSpacing / columns)
key(items, columns) {
items.chunked(columns).forEach { rowList ->
Row(modifier = Modifier.padding(mainAxisPadding)) {
rowList.forEach {
child(it, crossAxisPadding, 1f)
}
val emptyRows = (columns - rowList.size)
repeat(emptyRows) {
Spacer(modifier = Modifier.weight(1f))
}
}
}
}
}
}
@Composable
internal fun GridItem(location: ItemLocation, innerPadding: InnerPadding, weight: Float, onClick: (ItemLocation) -> Unit) {
ConstraintLayout(modifier = Modifier.preferredHeight(150.dp)
.weight(weight)
.padding(innerPadding.copy(top = 4.dp, bottom = 4.dp))
.clip(RoundedCornerShape(10.dp))
.background(location.safeColor)
.clickable(onClick = { onClick(location) })
) {
val (icon, title, itemCount) = createRefs()
Text(
modifier = Modifier.constrainAs(icon) {
end.linkTo(parent.end, 16.dp)
top.linkTo(parent.top, 8.dp)
},
text = "🥶",
style = MaterialTheme.typography.h5
)
Text(
modifier = Modifier.constrainAs(itemCount) {
start.linkTo(parent.start, 16.dp)
top.linkTo(parent.top, 8.dp)
},
text = "0 items",
style = MaterialTheme.typography.subtitle1
)
Text(
modifier = Modifier.constrainAs(title) {
start.linkTo(parent.start, 16.dp)
bottom.linkTo(parent.bottom, 8.dp)
end.linkTo(parent.end, 16.dp)
},
text = location.label,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = MaterialTheme.typography.h5
)
}
}
@Composable
fun LocationsList(
innerPadding: InnerPadding,
onClick: (ItemLocation) -> Unit
) {
Grid(
contentPadding = innerPadding,
mainAxisSpacing = 8.dp,
crossAxisSpacing = 8.dp,
items = result.value.data.orEmpty()
) { location, crossPadding, rowWeight ->
GridItem(location, crossPadding, rowWeight, onClick)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment