Last active
December 5, 2023 17:09
-
-
Save ch8n/e35244707bbf4b769970bc6caabd76ad to your computer and use it in GitHub Desktop.
Sharing Custom Logic with Compose
This file contains hidden or 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
// create properties | |
data class SharedToolbarProps( | |
val title: String, | |
val subtitle: String, | |
val isMenuIconVisible: Boolean, | |
val onMenuIconClicked: () -> Unit | |
) { | |
companion object { | |
val default: SharedToolbarProps = SharedToolbarProps( | |
title = "Lorem Title", | |
subtitle = "LoreIpsum subtitle", | |
isMenuIconVisible = true, | |
onMenuIconClicked = {} | |
) | |
} | |
} | |
// create store responsible for shared access | |
object SharedToolbarStore { | |
private val _toolbarProps = MutableStateFlow(SharedToolbarProps.default) | |
val toolbarProps = _toolbarProps.asStateFlow() | |
fun update(operation: (current: SharedToolbarProps) -> SharedToolbarProps) { | |
_toolbarProps.update(operation) | |
} | |
} | |
// create UI component that would be shared | |
@Composable | |
fun SharedToolbar(store: SharedToolbarStore = SharedToolbarStore) { | |
val props by store.toolbarProps.collectAsState() | |
Row( | |
modifier = Modifier.padding(16.dp).fillMaxWidth(), | |
horizontalArrangement = Arrangement.SpaceBetween | |
) { | |
Column( | |
verticalArrangement = Arrangement.SpaceBetween, | |
horizontalAlignment = Alignment.Start | |
) { | |
Text( | |
text = props.title, | |
fontSize = 14.sp | |
) | |
Text( | |
text = props.title, | |
fontSize = 10.sp | |
) | |
} | |
if (props.isMenuIconVisible) { | |
val clickableModifier = remember(props) { | |
Modifier.clickable(onClick = props.onMenuIconClicked) | |
} | |
Icon( | |
imageVector = Icons.Outlined.Menu, | |
contentDescription = null, | |
modifier = Modifier.then(clickableModifier) | |
) | |
} | |
} | |
} | |
// How to use? | |
Column( | |
verticalArrangement = Arrangement.spacedBy(8.dp), | |
horizontalAlignment = Alignment.CenterHorizontally | |
) { | |
val context = LocalContext.current | |
SharedToolbar() | |
Button(onClick = { | |
// you can shift it to different viewmodel and get access to SharedToolbarStore using DI solution | |
val currentStore = SharedToolbarStore | |
currentStore.update { curr -> | |
curr.copy( | |
title = UUID.randomUUID().toString(), | |
subtitle = UUID.randomUUID().toString(), | |
isMenuIconVisible = !curr.isMenuIconVisible, | |
onMenuIconClicked = { | |
Toast.makeText(context, UUID.randomUUID().toString(), Toast.LENGTH_SHORT) | |
.show() | |
} | |
) | |
} | |
}) { | |
Text(text = "Update Title") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment