In our application, there are many custom views that all are card with 3 slots header, content and bottom part, so I thought we can handle it with a scaffold inside the card except having many if/else conditions
So I created this base composable function ->
@Composable
fun DynamicTile(
modifier: Modifier = Modifier,
headContent: @Composable () -> Unit,
mainContent: @Composable (PaddingValues) -> Unit = { },
bottomContent: @Composable () -> Unit = { }
) {
Card( modifier = modifier) {
Scaffold(
topBar = headContent,
content = mainContent,
bottomBar = bottomContent
)
}
}
then different implementation for different purposes, I mention here two purposes e.g. showing specific image, animation, map and ... ->
for this one you should add your local drawable to image to compile it
@Composable
fun TileTeaser( modifier: Modifier = Modifier) {
with(entity) {
DynamicTile(
// modifier = modifier.then(Modifier.height(250.dp)),
headContent = {
Text(
text = "headline",
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, top = 8.dp)
)
},
mainContent = {
val painter = rememberImagePainter(
data = painterResource(R.drawable.ds_ic_add))
Image(
contentScale = ContentScale.Crop,
painter = painter,
modifier = modifier,
contentDescription = null
)
},
bottomContent = {
Box(modifier = Modifier.fillMaxWidth()) {
Button(
onClick = { }, modifier = Modifier
.align(Alignment.Center)
.wrapContentSize()
) {
Text(text = "Button")
}
}
}
}
)
}
}
And this one for animation with Lottie, you should add local raw to compile it
@Composable
fun TileAnimation(modifier: Modifier = Modifier) {
DynamicTile(
modifier = modifier.then(Modifier.height(300.dp)),
headContent = {
Text(
text = "headline",
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, top = 8.dp)
)
},
mainContent = {
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.sth))
Card(
modifier = Modifier
.height(183.dp)
.then(modifier),
shape = RoundedCornerShape(0.dp)
) {
LottieAnimation(
composition = composition,
modifier = modifier
.fillMaxSize(),
contentScale = ContentScale.Crop,
)
}
},
bottomContent = {
Box(modifier = Modifier.fillMaxWidth()) {
Button(
onClick = { }, modifier = Modifier
.align(Alignment.Center)
.wrapContentSize()
) {
Text(text = "Button")
}
}
}
)
}
Then I load them in column like this
@Composable
fun LoadScreen() {
Column(
modifier = Modifier
.padding(16.dp)
.verticalScroll(rememberScrollState())
) {
Text(text = "Teaser")
TileTeaser(
modifier = Modifier.padding(top = 16.dp)
)
Text(
text = "Animation",
modifier = Modifier.padding(top = 16.dp)
)
TileAnimation(modifier = Modifier.padding(vertical = 16.dp))
}
}
As you see if I comment the Modifier.height of the card, it crashes with this error ->
java.lang.IllegalArgumentException: Can't represent a size of 2147483563 in Constraints
at androidx.compose.ui.unit.Constraints$Companion.bitsNeedForSize(Constraints.kt:408)
at androidx.compose.ui.unit.Constraints$Companion.createConstraints-Zbe2FdA$ui_unit_release(Constraints.kt:368)
Kotlin version 1.6.10 and compose 1.1.0 and this is lottie library ->
implementation "com.airbnb.android:lottie-compose:4.2.2"
BTW, you can download Lottie file from here
Thank you in advance for your help