Introduction
Now that our CMP project is set up, let's build something useful. In this part, we'll create a small app: Quotes of the Day. We'll show a list of quotes, with the ability to favorite/unfavorite them — all written in shared UI code.
Step 1: Create QuoteCard
Inside commonMain
:
QuoteCard.ktkotlin
1@Composable2fun QuoteCard(3 text: String,4 author: String,5 isFavorite: Boolean,6 onToggleFavorite: () -> Unit7) {8 Card(modifier = Modifier.padding(8.dp).fillMaxWidth()) {9 Column(Modifier.padding(16.dp)) {10 Text(text, style = MaterialTheme.typography.bodyLarge)11 Spacer(Modifier.height(8.dp))12 Text("- $author", style = MaterialTheme.typography.labelMedium)13 Spacer(Modifier.height(8.dp))14 Button(onClick = onToggleFavorite) {15 Text(if (isFavorite) "★ Unfavorite" else "☆ Favorite")16 }17 }18 }19}
Step 2: Add QuotesScreen
QuotesScreen.ktkotlin
1data class Quote(val text: String, val author: String, var favorite: Boolean = false)23@Composable4fun QuotesScreen() {5 var quotes by remember {6 mutableStateListOf(7 Quote("Compose once, run anywhere.", "JetBrains"),8 Quote("Simplicity is the soul of efficiency.", "Austin Freeman"),9 Quote("Stay hungry, stay foolish.", "Steve Jobs")10 )11 }1213 LazyColumn {14 items(quotes.size) { index ->15 val quote = quotes[index]16 QuoteCard(17 text = quote.text,18 author = quote.author,19 isFavorite = quote.favorite20 ) {21 quotes = quotes.toMutableList().also {22 it[index] = it[index].copy(favorite = !quote.favorite)23 }24 }25 }26 }27}
Step 3: Run on Android
In androidMain/MainActivity.kt
:
MainActivity.ktkotlin
1class MainActivity : ComponentActivity() {2 override fun onCreate(savedInstanceState: Bundle?) {3 super.onCreate(savedInstanceState)4 setContent { QuotesScreen() }5 }6}
Quick Tip: Select androidApp → ▶ Run → your app runs in emulator/device.
Continue the Journey: You now have a shared UI running on Desktop and Android. In Part 3, we'll bring iOS into the mix.