I am making an app in Android Studio using Jetpack Compose. I have a "Welcome Page" on my app. Swiping up will reveal several login options in a sheet that will come from the bottom. But I want it to look like the page & sheet are stacked on top of each other, and by swiping up the user will push up the page & reveal the sheet. I added some sketches to show you what I mean. They are not perfect but I hope you understand it. The first picture is the normal state, the second one is the opened one.Rough sketch of my idea
I tried to use ModalBottomSheet, but since it just appears from the bottom, onto the page itself, it wasn't the way I wanted it to be.
There is no standalone BottomSheet
Composable that you can use, but you can get a very similar result by using a drawBehind
Modifier and drawing a custom border.
Please have a look at the following code:
@Composable
fun WelcomeScreen() {
val cornerRadius = 50.dp
val cornerRadiusPx = with(LocalDensity.current) { cornerRadius.toPx() }
val cardBrush = CardDefaults.outlinedCardBorder(true).brush
val cardStrokeWidthPx = with(LocalDensity.current) { CardDefaults.outlinedCardBorder(true).width.toPx() }
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
item {
Column(
modifier = Modifier.drawBehind {
val y = size.height
val x = size.width
drawLine(
brush = cardBrush,
start = Offset(cornerRadiusPx, y),
end = Offset(x - cornerRadiusPx, y),
strokeWidth = cardStrokeWidthPx
)
drawArc(
brush = cardBrush,
startAngle = 90f,
sweepAngle = 90f,
useCenter = false,
topLeft = Offset(0f, y - cornerRadiusPx * 2),
size = Size(cornerRadiusPx * 2, cornerRadiusPx * 2),
style = Stroke(width = cardStrokeWidthPx)
)
drawArc(
brush = cardBrush,
startAngle = 0f,
sweepAngle = 90f,
useCenter = false,
topLeft = Offset(x - cornerRadiusPx * 2, y - cornerRadiusPx * 2),
size = Size(cornerRadiusPx * 2, cornerRadiusPx * 2),
style = Stroke(width = cardStrokeWidthPx)
)
}
) {
Column(
modifier = Modifier
.padding(start = 2.dp, top = 2.dp, end = 2.dp, bottom = cornerRadius)
.fillParentMaxSize()
.padding(24.dp),
verticalArrangement = Arrangement.SpaceBetween,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("\nWELCOME\n", fontSize = 32.sp, fontWeight = FontWeight.Bold)
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Log in or Sign up")
Icon(
imageVector = Icons.Default.KeyboardArrowDown,
"Login"
)
}
}
}
}
item {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
FilledTonalButton(
modifier = Modifier.fillMaxWidth(),
onClick = {}
) {
Text("LOG IN")
}
OutlinedButton(
modifier = Modifier.fillMaxWidth(),
onClick = {}
) {
Text("REGISTER")
}
}
}
}
}
We use a LazyColumn
so that the content
is scrollable easily. Then we define one Column with our custom border using drawBehind
. Inside we place another Column that uses the fillParentMaxSize
Modifier so that it fills the whole screen at the beginning.
I am using the brush
and stroke width
from CardDefaults
, feel free to use any other color or stroke width instead.
Output: