Skip to content

Instantly share code, notes, and snippets.

@valin4tor
Last active July 6, 2021 14:13
Show Gist options
  • Save valin4tor/0d1a223948a37766b09340b0100cb836 to your computer and use it in GitHub Desktop.
Save valin4tor/0d1a223948a37766b09340b0100cb836 to your computer and use it in GitHub Desktop.
A recreation of iOS-style sheets using Jetpack Compose
package co.zimly.experimentalpha
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.scale
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import co.zimly.experimentalpha.ui.theme.ExperimentAlphaTheme
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() {
@ExperimentalMaterialApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ExperimentAlphaTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
MyApp()
}
}
}
}
}
@ExperimentalMaterialApi
@Composable
fun MyApp() {
val scope = rememberCoroutineScope()
val scaffoldState = rememberBottomSheetScaffoldState()
val sheetState = scaffoldState.bottomSheetState
// `sheetState.isExpanded` only updates when the sheet is finished animating.
// On the other hand, our custom `isExpanded` updates as soon as the sheet
// animation starts, in order to animate the background content simultaneously.
var isExpanded by remember { mutableStateOf(false) }
when (sheetState.direction) {
// sheet is moving down
1f -> isExpanded = false
// sheet is moving up
-1f -> isExpanded = true
// sheet has reached the top
0f -> if (sheetState.isExpanded) isExpanded = true
}
// 0.875 = 7/8
val blurAmount by animateFloatAsState(if (isExpanded) 0.875f else 1f)
BackHandler(sheetState.isExpanded) {
scope.launch {
sheetState.collapse()
}
}
BottomSheetScaffold(
sheetContent = {
Column(
Modifier
.fillMaxSize()
.padding(16.dp)
) {
Row {
Text("I'm a sheet!")
Spacer(Modifier.weight(1f))
Button(onClick = {
scope.launch {
sheetState.collapse()
}
}) {
Text("Close")
}
}
Spacer(Modifier.height(16.dp))
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec efficitur velit et nunc tempus, in aliquam felis condimentum. Quisque sit amet sem dui. Phasellus vel eros vulputate, scelerisque metus ac, feugiat justo. Nulla eget interdum nunc. Suspendisse imperdiet nibh a massa commodo, sed consequat turpis mollis. Nam lobortis sem sit amet ex pellentesque consectetur. Nunc libero quam, porta in consequat ac, aliquet sed ipsum. Nam molestie tincidunt nulla, a auctor ante commodo sed. Vivamus convallis rhoncus risus, et scelerisque justo consequat at. Nam metus est, vehicula sed enim id, condimentum vulputate risus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer tempus felis eu sollicitudin malesuada. Praesent non venenatis erat, eu euismod augue. Interdum et malesuada fames ac ante ipsum primis in faucibus.")
Spacer(Modifier.height(16.dp))
Text("Donec bibendum consectetur viverra. Nulla non molestie ex, quis efficitur felis. Phasellus sit amet rutrum purus. In hac habitasse platea dictumst. Fusce venenatis semper nisl, eget congue metus accumsan ac. Sed sed molestie nisi, vitae efficitur nibh. Donec at lectus sit amet elit commodo dignissim. Ut interdum non ex non sodales. Nulla ultrices ligula eu neque tempor porta sed at eros. Proin aliquet ligula odio, non convallis elit rhoncus eu.")
}
},
scaffoldState = scaffoldState,
sheetPeekHeight = 0.dp,
) { innerPadding ->
Box(
Modifier
.background(if (isSystemInDarkTheme()) MaterialTheme.colors.background else MaterialTheme.colors.primaryVariant)
.fillMaxSize()
.scale(blurAmount)
.alpha(blurAmount)
.padding(innerPadding)
) {
Scaffold(
topBar = {
TopAppBar(title = { Text("Hello, Twitter!") })
},
bottomBar = {
BottomNavigation() {
}
},
) { innerPadding ->
Column(
Modifier
.padding(innerPadding)
.padding(16.dp)
) {
Text("I hope you're having a wonderful day!")
Spacer(Modifier.height(16.dp))
Button(onClick = {
scope.launch {
sheetState.expand()
}
}) {
Text("Show sheet")
}
}
}
}
}
}
@ExperimentalMaterialApi
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
ExperimentAlphaTheme {
MyApp()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment