Skip to content

Instantly share code, notes, and snippets.

@ch8n
Last active December 5, 2023 17:09
Show Gist options
  • Save ch8n/e35244707bbf4b769970bc6caabd76ad to your computer and use it in GitHub Desktop.
Save ch8n/e35244707bbf4b769970bc6caabd76ad to your computer and use it in GitHub Desktop.
Sharing Custom Logic with Compose
// 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