-
Notifications
You must be signed in to change notification settings - Fork 6
1. Getting Started
The best way to get started is by creating a HelloWorld type of app, are you ready?
A simple Component will look something like this:
class HelloWorldComponent : Component() {
private val helloWorldState = HelloWorldState()
@Composable
override fun Content(modifier: Modifier) {
// We want to handle back press events in this Component so we add a BackPressHandler
BackPressHandler { backPressedCallbackHandler.onBackPressed() }
HelloWorldView(helloWorldState)
}
}
@Composable
private fun HelloWorldView(helloWorldState: HelloWorldState) {
val userName = helloWorldState.userName
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Enter your name:")
OutlinedTextField(
value = userName,
onValueChange = {
helloWorldState.userName = it
}
)
Text("Great to meet you: $userName")
}
}
private class HelloWorldState {
var userName by mutableStateOf("")
}
When you run above code you will get the following screen outputs:
Woola!
You have created an application that runs in all the platforms. The code in each platform is pretty much the same and looks like bellow:
// Android
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CompositionLocalProvider(
LocalBackPressedDispatcher provides AndroidBackPressDispatcher(this@MainActivity),
) {
ComposeApp(
onExit = { finish() }
)
}
}
}
}
// JVM
fun main() =
singleWindowApplication(
title = "Hello World",
state = WindowState(size = DpSize(500.dp, 800.dp))
) {
val jvmBackPressDispatcher = remember {
DefaultBackPressDispatcher()
}
CompositionLocalProvider(
LocalBackPressedDispatcher provides jvmBackPressDispatcher,
) {
Box(modifier = Modifier.fillMaxSize()) {
ComposeApp(
onExit = {
exitProcess(0)
}
)
FloatingButton(
modifier = Modifier.offset(y = 48.dp),
alignment = Alignment.TopStart,
onClick = { jvmBackPressDispatcher.dispatchBackPressed() }
)
}
}
}
// Browser
fun main() {
onWasmReady {
Window("Hello World") {
val webBackPressDispatcher = remember {
DefaultBackPressDispatcher()
}
CompositionLocalProvider(
LocalBackPressedDispatcher provides webBackPressDispatcher,
) {
Box(modifier = Modifier.fillMaxSize()) {
ComposeApp(
onExit = {
// Should hide back button
}
)
FloatingButton(
modifier = Modifier.offset(y = 48.dp),
alignment = Alignment.TopStart,
onClick = { webBackPressDispatcher.dispatchBackPressed() }
)
}
}
}
}
}
In the code above, in the JVM and the Browser platforms, I added a FloatingButton{}
composable to artificially mock a back button type of navigation. This platforms do not have a hardware back button built in and I wanted one, but is up to you, a back button is not needed in these platforms anyways.
As you can see, the code is pretty much the same in all the platforms and the good thing is, it barely change per app. The only code that will vary per app, is the ComposeAppState class.
class ComposeAppState {
private val HelloWorldComponent: Component = HelloWorldComponent()
private var onBackPressEventLastCopy: () -> Unit = {}
init {
HelloWorldComponent.context. rootBackPressedCallbackDelegate = ForwardBackPressCallback {
onBackPressEventLastCopy()
}
}
fun start() {
HelloWorldComponent.start()
}
fun stop() {}
@Composable
fun PresentContent(
onBackPressEvent: () -> Unit = {}
) {
onBackPressEventLastUpdate = onBackPressEvent
HelloWorldComponent.Content(Modifier)
}
}
Code taken from HelloWorld example.
In this class body you will decide what component type to create as a root of all components and how to build your tree and interact with the different platforms apis. Now that you know how to create a component-tree App you will go to a more complex case, container components.