Skip to content

Instantly share code, notes, and snippets.

@zivkesten
Last active May 30, 2022 18:09
Show Gist options
  • Save zivkesten/6adf14868332f8b173b9176b4c2dc475 to your computer and use it in GitHub Desktop.
Save zivkesten/6adf14868332f8b173b9176b4c2dc475 to your computer and use it in GitHub Desktop.
An activity that can be extended and can display composables as a bottom sheet
/*
To extend this class, make sure it's descendants
add android:theme="@style/Theme.Transparent" to it's manifest tag
*/
@OptIn(ExperimentalMaterialApi::class)
abstract class ComposeBottomSheetActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val coroutineScope = rememberCoroutineScope()
val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
val isSheetOpened = remember { mutableStateOf(false) }
ModalBottomSheetLayout(
sheetState = modalBottomSheetState,
sheetContent = {
ScreenContent(coroutineScope, modalBottomSheetState) {
onFinish(coroutineScope, modalBottomSheetState)
}
}
) {}
// Take action based on hidden state
LaunchedEffect(modalBottomSheetState.currentValue) {
when (modalBottomSheetState.currentValue) {
ModalBottomSheetValue.Hidden -> {
handleBottomSheetAtHiddenState(
isSheetOpened,
modalBottomSheetState
)
}
}
}
BackHandler {
onFinish(coroutineScope, modalBottomSheetState)
}
}
}
// Helper methods
private suspend fun handleBottomSheetAtHiddenState(
modalLayoutInitialized: MutableState<Boolean>,
modalBottomSheetState: ModalBottomSheetState
) {
when {
!modalLayoutInitialized.value -> initializeModalLayout(modalLayoutInitialized, modalBottomSheetState)
else -> exit()
}
}
private suspend fun initializeModalLayout(
isSheetOpened: MutableState<Boolean>,
modalBottomSheetState: ModalBottomSheetState
) {
isSheetOpened.value = true
modalBottomSheetState.show()
}
open fun exit() = finish()
private fun onFinish(
coroutineScope: CoroutineScope,
modalBottomSheetState: ModalBottomSheetState,
withResults: Boolean = false,
result: Intent? = null
) {
coroutineScope.launch {
if (withResults) setResult(RESULT_OK)
result?.let { intent = it}
modalBottomSheetState.hide() // will trigger the LaunchedEffect
}
}
@Composable
abstract fun ScreenContent(
coroutineScope: CoroutineScope,
modalBottomSheetState: ModalBottomSheetState,
onExit: (() -> Unit?)
)
override fun onPause() {
super.onPause()
overridePendingTransition(0, 0)
}
companion object {
private val TAG = ComposeBottomSheetActivity::class.java.simpleName
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment