Last active
June 3, 2024 14:36
-
-
Save zivkesten/73c96b268b3991eb1208ad0a74a2362b to your computer and use it in GitHub Desktop.
Extension functions to display a Jetpack Compose bottom sheet over Android view
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Extension for Activity | |
fun Activity.showAsBottomSheet(content: @Composable (() -> Unit) -> Unit) { | |
val viewGroup = this.findViewById(android.R.id.content) as ViewGroup | |
addContentToView(viewGroup, content) | |
} | |
// Extension for Fragment | |
fun Fragment.showAsBottomSheet(content: @Composable (() -> Unit) -> Unit) { | |
val viewGroup = requireActivity().findViewById(android.R.id.content) as ViewGroup | |
addContentToView(viewGroup, content) | |
} | |
// Helper method | |
private fun addContentToView( | |
viewGroup: ViewGroup, | |
content: @Composable (() -> Unit) -> Unit | |
) { | |
viewGroup.addView( | |
ComposeView(viewGroup.context).apply { | |
setContent { | |
BottomSheetWrapper(viewGroup, this, content) | |
} | |
} | |
) | |
} | |
@OptIn(ExperimentalMaterialApi::class) | |
@Composable | |
private fun BottomSheetWrapper( | |
parent: ViewGroup, | |
composeView: ComposeView, | |
content: @Composable (() -> Unit) -> Unit | |
) { | |
val TAG = parent::class.java.simpleName | |
val coroutineScope = rememberCoroutineScope() | |
val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden) | |
var isSheetOpened by remember { mutableStateOf(false) } | |
ModalBottomSheetLayout( | |
sheetBackgroundColor = Color.Transparent, | |
sheetState = modalBottomSheetState, | |
sheetContent = { | |
content { | |
// Action passed for clicking close button in the content | |
coroutineScope.launch { | |
modalBottomSheetState.hide() // will trigger the LaunchedEffect | |
} | |
} | |
} | |
) {} | |
BackHandler { | |
coroutineScope.launch { | |
modalBottomSheetState.hide() // will trigger the LaunchedEffect | |
} | |
} | |
// Take action based on hidden state | |
LaunchedEffect(modalBottomSheetState.currentValue) { | |
when (modalBottomSheetState.currentValue) { | |
ModalBottomSheetValue.Hidden -> { | |
when { | |
isSheetOpened -> parent.removeView(composeView) | |
else -> { | |
isSheetOpened = true | |
modalBottomSheetState.show() | |
} | |
} | |
} | |
else -> { | |
Log.i(TAG, "Bottom sheet ${modalBottomSheetState.currentValue} state") | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment