Kotlin Multiplatform Development Help

Modify the project

Let's modify the code generated by the Kotlin Multiplatform wizard and display the current date within the App composable. To do this, you'll add a new dependency to the project, enhance the UI, and rerun the application on each platform.

Add a new dependency

You could retrieve the date using platform-specific libraries and expected and actual declarations. But we recommend that you use this approach only when there's no Kotlin Multiplatform library available. In this case, you can rely on the kotlinx-datetime library.

To use this library:

  1. Open the composeApp/build.gradle.kts file and add it as a dependency to the project.

    kotlin { // ... sourceSets { // ... commonMain.dependencies { // ... implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0") } wasmJsMain.dependencies { implementation(npm("@js-joda/timezone", "2.3.0")) } } }
    • The main dependency is added to the section that configures the common code source set.

    • For simplicity, the version number is included directly instead of being added to the version catalog.

    • To support timezones in the web target, the reference to the necessary npm package is included in wasmJsMain dependencies.

  2. Once the dependency is added, you're prompted to resync the project. Click Sync Now to synchronize Gradle files:

    Synchronize Gradle files
  3. In the terminal, navigate to your project directory and run:

    ./gradlew kotlinUpgradeYarnLock

    This Gradle task ensures that the yarn.lock file is updated with the latest dependency versions.

Enhance the user interface

  1. Open the composeApp/src/commonMain/kotlin/App.kt file and add the following function which returns a string containing the current date:

    fun todaysDate(): String { fun LocalDateTime.format() = toString().substringBefore('T') val now = Clock.System.now() val zone = TimeZone.currentSystemDefault() return now.toLocalDateTime(zone).format() }
  2. In the same file, modify the App() composable to include the Text() composable that invokes this function and displays the result:

    @Composable @Preview fun App() { MaterialTheme { var showContent by remember { mutableStateOf(false) } val greeting = remember { Greeting().greet() } Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { Text( text = "Today's date is ${todaysDate()}", modifier = Modifier.padding(20.dp), fontSize = 24.sp, textAlign = TextAlign.Center ) Button(onClick = { showContent = !showContent }) { Text("Click me!") } AnimatedVisibility(showContent) { Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { Image(painterResource(Res.drawable.compose_multiplatform), null) Text("Compose: $greeting") } } } } }
  3. Follow the IDE's suggestions to import the missing dependencies.

    Unresolved references
  4. Switch the web app from using an Element as a container to an HTML element with an externally specified id:

    1. In the composeApp/src/wasmJsMain/resources/index.html file, add a named element within the <body>:

      <body> <div id="composeApplication" style="width:400px; height: 500px;"></div> </body>
    2. In the composeApp/src/wasmJsMain/kotlin/main.kt file, change the ComposeViewport call to the String variant, pointing to the ID you specified in the HTML file:

      @OptIn(ExperimentalComposeUiApi::class) fun main() { ComposeViewport(viewportContainerId = "composeApplication") { App() } }

Rerun the application

You can now rerun the application using the same run configurations for Android, iOS, desktop, and web:

First Compose Multiplatform app on Android and iOS
First Compose Multiplatform app on desktop
First Compose Multiplatform app on web

Next step

In the next part of the tutorial, you'll learn new Compose Multiplatform concepts and create your own application from scratch.

Proceed to the next part

Get help

Last modified: 25 September 2024