Reputation: 390
I want to create a dashboard and I want this kind of layout on top. How do I achieve a layout like this one in jetpack compose? top dashboard layout, top dashboard layout 2
Upvotes: 7
Views: 15577
Reputation: 1662
If you want to create a stack view with a list of content you can do that with the below code, here Arrangement.spacedBy((-50).dp) is used for giving the stack effect.
@Composable
fun CardsStackView(cards: List<CardUiModel> = getMockedCards()) {
LazyColumn(
verticalArrangement = Arrangement.spacedBy((-50).dp),
modifier = Modifier
.padding(top = 50.dp, end = 10.dp, start = 10.dp)
) {
itemsIndexed(cards) { index, card ->
CardView(index, card)
}
}
}
@Composable
fun CardView(index: Int, cardUiModel: CardUiModel) {
Card(
shape = RoundedCornerShape(8.dp),
modifier = Modifier
.height(80.dp)
.width(260.dp)
) {
Surface(
modifier = Modifier.fillMaxSize(),
color = getCardColor(index)
) {
Box(contentAlignment = Center) {
Text(text = cardUiModel.name)
}
}
}
}
private fun getMockedCards() = listOf(
CardUiModel("Visa"),
CardUiModel("Amex"),
CardUiModel("Rupay"),
CardUiModel("Master Card")
)
private fun getCardColor(index: Int) =
when (index) {
0 -> Color.Blue
1 -> Color.Magenta
2 -> Color.Cyan
3 -> Color.Red
else -> Color.Yellow
}
data class CardUiModel(val name: String)
@Preview(showBackground = true, device = Devices.PIXEL_XL)
@Composable
fun CardsStackViewPreview() {
MaterialTheme {
CardsStackView()
}
}
It will look like the below Image
Upvotes: 4
Reputation: 67248
You can use a Box or BoxWithConstraints to achieve that look. The key thing here is to align the one in center to bottom and add bottom padding as big as the sum of height of Composable at the bottom and the half height of at the bottom since your Composables at the bottom and at the top don't have equal heights.
@Composable
private fun MyComposable(modifier: Modifier = Modifier) {
BoxWithConstraints(modifier = modifier.fillMaxWidth(1f)) {
val maxHeight = this.maxHeight
val topHeight: Dp = maxHeight * 2 / 3
val bottomHeight: Dp = maxHeight / 3
val centerHeight = 100.dp
val centerPaddingBottom = bottomHeight - centerHeight / 2
Top(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.TopCenter)
.height(topHeight)
)
Bottom(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter)
.height(bottomHeight)
)
Center(
modifier = Modifier
.padding(start = 10.dp, end = 10.dp, bottom = centerPaddingBottom)
.fillMaxWidth()
.height(centerHeight)
.align(Alignment.BottomCenter)
)
}
}
@Composable
private fun Top(modifier: Modifier) {
Column(modifier.background(Blue400)) {
}
}
@Composable
private fun Bottom(modifier: Modifier) {
Column(modifier.background(Color.White)) {
}
}
@Composable
fun Center(modifier: Modifier) {
Column(modifier.background(Color.Red, shape = RoundedCornerShape(10.dp))) {
}
}
Result
Upvotes: 8
Reputation: 13488
Generally you can use a Box.
See the example here https://foso.github.io/Jetpack-Compose-Playground/layout/box/
Box(Modifier.fillMaxSize()) {
Text("This text is drawn first", modifier = Modifier.align(Alignment.TopCenter))
Box(
Modifier.align(Alignment.TopCenter).fillMaxHeight().width(
50.dp
).background( Color.Blue)
)
Text("This text is drawn last", modifier = Modifier.align(Alignment.Center))
FloatingActionButton(
modifier = Modifier.align(Alignment.BottomEnd).padding(12.dp),
onClick = {}
) {
Text("+")
}
}
Upvotes: 0