Skip to content

Instantly share code, notes, and snippets.

@DevPicon
Created December 19, 2024 16:36
Show Gist options
  • Save DevPicon/e42b17ab45f07011a80d3dd2666d9899 to your computer and use it in GitHub Desktop.
Save DevPicon/e42b17ab45f07011a80d3dd2666d9899 to your computer and use it in GitHub Desktop.
[Android] Custom Snackbar Demo
data class CustomMode(val mode: Mode, val name: String, val minValue: Int, val maxValue: Int)
enum class Mode {
ONE, TWO, THREE, UNDEFINED
}
@Composable
fun CustomSnackbarDemo(
modifier: Modifier = Modifier,
) {
val viewModel: CustomSnackbarViewModel = viewModel()
val state by viewModel.customSnackbarState.collectAsState()
val snackbarHostState = remember { SnackbarHostState() }
var retryCount by remember { mutableIntStateOf(0) }
val scope = rememberCoroutineScope()
var currentMode by remember { mutableStateOf(CustomMode(Mode.UNDEFINED, "", 0, 0)) }
when (state) {
is CustomSnackbarState.Offline -> {
Button(
onClick = {
viewModel.turnOn()
}
) {
Text("turn On")
}
}
is CustomSnackbarState.Online -> {
val onlineState = state as CustomSnackbarState.Online
if (onlineState.hasModeChangeFailed) {
LaunchedEffect(retryCount) {
snackbarHostState.currentSnackbarData?.dismiss()
snackbarHostState.showSnackbar(
message = "Mode change failed",
actionLabel = "Retry",
duration = SnackbarDuration.Long
)
}
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Box(
Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
SnackbarHost(
hostState = snackbarHostState
) { snackbarData ->
CustomSnackbar(
title = "Mode change failed",
message = snackbarData.visuals.message,
showAction = retryCount < 3,
actionLabel = snackbarData.visuals.actionLabel ?: "Try again",
onAction = {
retryCount++
viewModel.executeEvent(currentMode)
}
)
}
}
}
} else {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
// Button to trigger Snackbar
Button(
onClick = {
val successMode = CustomMode(Mode.TWO, "Success", 1, 1)
currentMode = successMode
viewModel.executeEvent(currentMode)
}
) {
Text("Send Success")
}
// Button to trigger Snackbar
Button(
onClick = {
val failureMode = CustomMode(Mode.THREE, "Failure", 2, 2)
currentMode = failureMode
viewModel.executeEvent(currentMode)
}
) {
Text("Send Failure")
}
}
}
}
}
}
@Composable
fun CustomSnackbar(
title: String,
message: String,
showAction: Boolean,
actionLabel: String,
onAction: () -> Unit
) {
Surface(
color = Color.White,
shape = MaterialTheme.shapes.medium,
shadowElevation = 2.dp,
) {
Row(
Modifier
.padding(16.dp)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Row(Modifier.fillMaxWidth()) {
Column(Modifier.weight(1f)) {
Text(
text = title,
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
color = Color.Black
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = message,
fontSize = 14.sp,
color = Color.Gray
)
}
if (showAction) {
TextButton(onClick = onAction) {
Text(
text = actionLabel,
fontSize = 14.sp,
fontWeight = FontWeight.Bold,
textDecoration = TextDecoration.Underline,
color = Color.Black
)
}
}
}
}
}
}
@Preview
@Composable
private fun CustomSnackbarDemoPreview() {
CustomSnackbarDemo()
}
class CustomSnackbarViewModel : ViewModel() {
private var _customSnackbarState =
MutableStateFlow<CustomSnackbarState>(CustomSnackbarState.Offline)
val customSnackbarState = _customSnackbarState
fun executeEvent(selectedMode: CustomMode) {
when (selectedMode.mode) {
Mode.ONE -> _customSnackbarState.value = CustomSnackbarState.Offline
Mode.THREE -> _customSnackbarState.update { state ->
if (state is CustomSnackbarState.Online) {
state.copy(hasModeChangeFailed = true)
} else {
CustomSnackbarState.Online(hasModeChangeFailed = true)
}
}
Mode.TWO,
Mode.UNDEFINED -> _customSnackbarState.update { state ->
CustomSnackbarState.Online()
}
}
}
fun turnOn() {
_customSnackbarState.update {
CustomSnackbarState.Online()
}
}
}
sealed class CustomSnackbarState {
data object Offline : CustomSnackbarState()
data class Online(val hasModeChangeFailed: Boolean = false) : CustomSnackbarState()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment