-
-
Save andrew-levy/a200152de34bd3382c536b8dc4ec6669 to your computer and use it in GitHub Desktop.
package expo.modules.jetpackcomposeview | |
import android.content.Context | |
import androidx.compose.animation.animateColorAsState | |
import androidx.compose.animation.core.animateFloatAsState | |
import androidx.compose.foundation.layout.Arrangement | |
import androidx.compose.foundation.layout.Column | |
import androidx.compose.foundation.layout.fillMaxSize | |
import androidx.compose.foundation.layout.padding | |
import androidx.compose.material3.* | |
import androidx.compose.runtime.Composable | |
import androidx.compose.runtime.getValue | |
import androidx.compose.runtime.mutableStateOf | |
import androidx.compose.runtime.remember | |
import androidx.compose.runtime.setValue | |
import androidx.compose.ui.Alignment | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.graphics.Color | |
import androidx.compose.ui.graphics.graphicsLayer | |
import androidx.compose.ui.platform.ComposeView | |
import androidx.compose.ui.unit.dp | |
import expo.modules.kotlin.AppContext | |
import expo.modules.kotlin.views.ExpoView | |
class JetpackComposeView(context: Context, appContext: AppContext) : ExpoView(context, appContext) { | |
internal val composeView = ComposeView(context).also { | |
// add the compose view as a child | |
addView(it) | |
it.layoutParams = LayoutParams( | |
android.view.ViewGroup.LayoutParams.MATCH_PARENT, | |
android.view.ViewGroup.LayoutParams.MATCH_PARENT, | |
) | |
it.setContent { | |
Greeting("Compose") | |
} | |
} | |
// update the text | |
fun updateText(newValue: String) { | |
composeText.setContent { | |
Greeting(newValue) | |
} | |
} | |
} | |
// Composable here | |
@Composable | |
fun Greeting(name: String) { | |
var isChecked by remember { mutableStateOf(false) } | |
var isDialogOpen by remember { mutableStateOf(false) } | |
var sliderPosition by remember { mutableStateOf(0f) } | |
var animateText by remember { mutableStateOf(false) } | |
val scaleText by animateFloatAsState(targetValue = if (animateText) 1.5f else 1f, label = "") | |
val textColor by animateColorAsState(targetValue = if (animateText) Color.Blue else Color.Black, label = "") | |
Column( | |
modifier = Modifier.fillMaxSize(), | |
verticalArrangement = Arrangement.Center, | |
horizontalAlignment = Alignment.CenterHorizontally | |
) { | |
Text( | |
text = "Expo + $name!", | |
style = MaterialTheme.typography.titleLarge, | |
color = textColor, | |
modifier = Modifier.graphicsLayer(scaleX = scaleText, scaleY = scaleText) | |
) | |
Button( | |
onClick = { | |
animateText = !animateText | |
}, | |
modifier = Modifier.padding(16.dp) | |
) { Text(text = "Animate") } | |
Switch( | |
checked = isChecked, | |
onCheckedChange = { isChecked = it }, | |
modifier = Modifier.padding(16.dp) | |
) | |
Slider( | |
value = sliderPosition, | |
onValueChange = { sliderPosition = it }, | |
modifier = Modifier.padding(16.dp) | |
) | |
Button( | |
onClick = { | |
isDialogOpen = true | |
}, | |
modifier = Modifier.padding(16.dp) | |
) { | |
Text(text = "Click Me") | |
} | |
if (isDialogOpen) { | |
AlertDialogExample( | |
onDismissRequest = { | |
isDialogOpen = false | |
}, | |
onConfirmation = { | |
isDialogOpen = false | |
}, | |
dialogTitle = "Dialog Title", | |
dialogText = "Dialog Text" | |
) | |
} | |
} | |
} | |
@OptIn(ExperimentalMaterial3Api::class) | |
@Composable | |
fun AlertDialogExample( | |
onDismissRequest: () -> Unit, | |
onConfirmation: () -> Unit, | |
dialogTitle: String, | |
dialogText: String, | |
) { | |
AlertDialog( | |
title = { | |
Text(text = dialogTitle) | |
}, | |
text = { | |
Text(text = dialogText) | |
}, | |
onDismissRequest = { | |
onDismissRequest() | |
}, | |
confirmButton = { | |
TextButton( | |
onClick = { | |
onConfirmation() | |
} | |
) { | |
Text("Confirm") | |
} | |
}, | |
dismissButton = { | |
TextButton( | |
onClick = { | |
onDismissRequest() | |
} | |
) { | |
Text("Dismiss") | |
} | |
} | |
) | |
} |
package expo.modules.jetpackcomposeview | |
import expo.modules.kotlin.modules.Module | |
import expo.modules.kotlin.modules.ModuleDefinition | |
class JetpackComposeViewModule : Module() { | |
override fun definition() = ModuleDefinition { | |
Name("JetpackComposeView") | |
View(JetpackComposeView::class) { | |
Prop("name") { view: JetpackComposeView, prop: String -> | |
view.updateText(prop) | |
println(prop) | |
} | |
} | |
} | |
} |
@corysimmons Thanks! You’ll need to add a bit of setup in your module’s build.gradle file. You can follow this: https://developer.android.com/jetpack/compose/setup
@corysimmons Thanks! You’ll need to add a bit of setup in your module’s build.gradle file. You can follow this: https://developer.android.com/jetpack/compose/setup
Hello @andrew-levy , can you please share with me the build.gradle file that you use to make jetpackCompose work with expo modules.
Module build.gradle example with compose:
https://github.com/andrew-levy/sweet-sheet/blob/main/android/build.gradle
(check the dependencies near the bottom)
Project build.gradle example:
https://github.com/andrew-levy/sweet-sheet/blob/main/example/android/build.gradle
(check line 22)
Very cool @andrew-levy ! 👏
I get errors about not being able to resolve Compose. Do you have instructions on adding those dependencies in an Expo project?