2 years ago
#51446
Joe Vienneau
Is there a way to reuse "common" things like DropdownMenu in Compose Multiplatform Project?
For the desktop, DropdownMenu is supplied by Gradle: org.jetbrains.compose.material:material-desktop:1.0.1-rc2; for Android it's in Gradle: androidx.compose.material:material:1.1.0-beta04@aar
I would have thought there would be a common API that both implemented.
I know that I could define my own interface/adapter and then plug in the device specific version, but I'm wondering if there is a clever idiomatic Kotlin way to do this.
I tried using 'expect' and 'actual', but I could figure out the syntax. (DropdownMenu doesn't have a simple signature like in the examples of expect/actual usage).
Here's an example of a Menu I'm using... the Android and Desktop versions look identical:
// TODO is there way that this can be moved to Common
@Composable
fun BellSoundMenu(model: SessionViewModel, files: List<SoundFile>) {
val selectedIndex = remember { mutableStateOf(0) }
DropdownMenu(
expanded = model.isBellMenuExpanded.value,
...
) {
files.forEachIndexed { index, sound: SoundFile ->
DropdownMenuItem(onClick = {
selectedIndex.value = index
...
}) {
Row {
val isSelected = sound == model.getBellFile()
Icon(
...
)
Text(
...
)
}
}
}
}
}
I'm looking for a way to move this to the Common folder and not duplicate code.
I ended up doing this; I created an interface:
interface MyDropdown {
@Composable
fun Menu(
expanded: Boolean,
onDismissRequest: () -> Unit,
modifier: Modifier,
content: @Composable (androidx.compose.foundation.layout.ColumnScope.() -> Unit)
)
@Composable
fun MenuItem(
onClick: () -> Unit,
content: @Composable (androidx.compose.foundation.layout.RowScope.() -> Unit)
)
}
And then a small object to do the forwarding:
val AndroidDropdown = object : MyDropdown {
@Composable
override fun Menu(
expanded: Boolean,
onDismissRequest: () -> Unit,
modifier: Modifier,
content: @Composable (androidx.compose.foundation.layout.ColumnScope.() -> Unit)
) {
return DropdownMenu(
expanded = expanded, onDismissRequest = onDismissRequest, modifier = modifier, content = content
)
}
@Composable
override fun MenuItem(
onClick: () -> Unit, content: @Composable RowScope.() -> Unit
) {
return DropdownMenuItem(onClick = onClick, content = content)
}
}
I'm still curious if there's a more Kotlin-esque way of doing it :)
kotlin
android-jetpack-compose
kotlin-multiplatform
compose-multiplatform
0 Answers
Your Answer