Hola amigos 馃憢 Bienvenidos a un nuevo tutorial de Universo Android. Hoy aprenderemos a crear aplicaciones multiplataforma con Jetpack Compose, permiti茅ndote escribir c贸digo una sola vez y ejecutarlo en Android, Desktop (Windows, macOS, Linux) y Web.
Al finalizar este tutorial tendr谩s:
- Proyecto Compose Multiplatform
- Aplicaci贸n para Android y Desktop
- C贸digo compartido entre plataformas
- UI adaptable
- Recursos espec铆ficos por plataforma
- Configuraci贸n completa
馃煩 1. ¿Qu茅 es Compose Multiplatform?
Compose Multiplatform es la evoluci贸n de Jetpack Compose que permite crear aplicaciones para m煤ltiples plataformas (Android, iOS, Desktop, Web) compartiendo c贸digo UI y l贸gica de negocio.
馃煩 2. Plataformas Soportadas
- Android: Apps m贸viles nativas
- Desktop: Windows, macOS, Linux
- iOS: Aplicaciones iOS (experimental)
- Web: Aplicaciones web (experimental)
馃煩 3. Crear Proyecto Multiplatform
Opci贸n 1: Usar Wizard de IntelliJ IDEA
- Descarga IntelliJ IDEA Community (gratis)
- New Project → Kotlin Multiplatform
- Selecciona: Android + Desktop
- Finaliza creaci贸n
Opci贸n 2: Crear Manualmente
馃煩 4. Estructura del Proyecto
MyComposeApp/
├── androidApp/ # C贸digo Android
│ └── src/
├── desktopApp/ # C贸digo Desktop
│ └── src/
├── common/ # C贸digo compartido
│ └── src/
│ ├── commonMain/ # C贸digo com煤n
│ ├── androidMain/ # Espec铆fico Android
│ └── desktopMain/ # Espec铆fico Desktop
└── build.gradle.kts馃煩 5. Configuraci贸n Gradle (Proyecto)
馃搫 build.gradle.kts (root)
plugins {
kotlin("multiplatform") version "1.9.20" apply false
id("com.android.application") version "8.1.4" apply false
id("org.jetbrains.compose") version "1.5.10" apply false
}馃煩 6. Configuraci贸n Gradle (Common)
馃搫 common/build.gradle.kts
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
id("com.android.library")
}
kotlin {
android()
jvm("desktop")
sourceSets {
val commonMain by getting {
dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.ui)
}
}
val androidMain by getting {
dependencies {
implementation("androidx.activity:activity-compose:1.8.2")
}
}
val desktopMain by getting {
dependencies {
implementation(compose.desktop.currentOs)
}
}
}
}
android {
namespace = "com.example.myapp.common"
compileSdk = 34
defaultConfig {
minSdk = 24
}
}馃煩 7. C贸digo Compartido
馃搫 common/src/commonMain/App.kt
package com.example.myapp
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun App() {
var showContent by remember { mutableStateOf(false) }
var counter by remember { mutableStateOf(0) }
MaterialTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// T铆tulo
Text(
text = "Compose Multiplatform",
style = MaterialTheme.typography.headlineLarge,
color = Color(0xFF2196F3)
)
Text(
text = "Una app, m煤ltiples plataformas",
style = MaterialTheme.typography.bodyLarge,
color = Color.Gray
)
Spacer(modifier = Modifier.height(16.dp))
// Informaci贸n de plataforma
PlatformInfoCard()
// Contador
CounterCard(counter) { counter++ }
// Bot贸n toggle
Button(
onClick = { showContent = !showContent },
modifier = Modifier.fillMaxWidth()
) {
Text(if (showContent) "Ocultar" else "Mostrar Contenido")
}
// Contenido animado
AnimatedVisibility(showContent) {
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = Color(0xFF4CAF50)
),
shape = RoundedCornerShape(16.dp)
) {
Column(
modifier = Modifier.padding(24.dp)
) {
Text(
"✓ C贸digo compartido",
color = Color.White
)
Text(
"✓ UI declarativa",
color = Color.White
)
Text(
"✓ Nativo en todas las plataformas",
color = Color.White
)
}
}
}
// Lista de caracter铆sticas
FeaturesSection()
}
}
}
}
@Composable
fun PlatformInfoCard() {
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = Color(0xFF2196F3)
),
shape = RoundedCornerShape(16.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
"Ejecutando en:",
style = MaterialTheme.typography.titleMedium,
color = Color.White
)
Text(
getPlatformName(),
style = MaterialTheme.typography.headlineMedium,
color = Color.White
)
}
}
}
@Composable
fun CounterCard(counter: Int, onIncrement: () -> Unit) {
Card(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(16.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
"Contador",
style = MaterialTheme.typography.titleLarge
)
Text(
"$counter",
style = MaterialTheme.typography.displayLarge,
color = Color(0xFFFF5722)
)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = onIncrement) {
Text("Incrementar")
}
}
}
}
@Composable
fun FeaturesSection() {
Card(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(16.dp)
) {
Column(
modifier = Modifier.padding(24.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(
"Caracter铆sticas",
style = MaterialTheme.typography.titleLarge,
color = Color(0xFF2196F3)
)
FeatureItem("馃摫", "Android nativo")
FeatureItem("馃捇", "Windows, macOS, Linux")
FeatureItem("馃帹", "UI moderna con Material 3")
FeatureItem("⚡", "Rendimiento nativo")
FeatureItem("馃攧", "Hot Reload")
}
}
}
@Composable
fun FeatureItem(icon: String, text: String) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(icon, style = MaterialTheme.typography.headlineSmall)
Text(text, style = MaterialTheme.typography.bodyLarge)
}
}
// Funci贸n expect (declaraci贸n)
expect fun getPlatformName(): String馃煩 8. Implementaci贸n Android
馃搫 common/src/androidMain/Platform.kt
package com.example.myapp
actual fun getPlatformName(): String {
return "Android ${android.os.Build.VERSION.SDK_INT}"
}馃煩 9. Implementaci贸n Desktop
馃搫 common/src/desktopMain/Platform.kt
package com.example.myapp
actual fun getPlatformName(): String {
val os = System.getProperty("os.name")
val arch = System.getProperty("os.arch")
return "$os ($arch)"
}馃煩 10. App Android
馃搫 androidApp/build.gradle.kts
plugins {
id("com.android.application")
kotlin("android")
id("org.jetbrains.compose")
}
android {
namespace = "com.example.myapp.android"
compileSdk = 34
defaultConfig {
applicationId = "com.example.myapp.android"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
}
}
dependencies {
implementation(project(":common"))
implementation("androidx.activity:activity-compose:1.8.2")
}馃搫 androidApp/src/main/MainActivity.kt
package com.example.myapp.android
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import com.example.myapp.App
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
App()
}
}
}馃煩 11. App Desktop
馃搫 desktopApp/build.gradle.kts
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
}
kotlin {
jvm {
withJava()
}
sourceSets {
val jvmMain by getting {
dependencies {
implementation(project(":common"))
implementation(compose.desktop.currentOs)
}
}
}
}
compose.desktop {
application {
mainClass = "MainKt"
nativeDistributions {
targetFormats(
org.jetbrains.compose.desktop.application.dsl.TargetFormat.Dmg,
org.jetbrains.compose.desktop.application.dsl.TargetFormat.Msi,
org.jetbrains.compose.desktop.application.dsl.TargetFormat.Deb
)
packageName = "MyComposeApp"
packageVersion = "1.0.0"
}
}
}馃搫 desktopApp/src/jvmMain/Main.kt
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import androidx.compose.ui.unit.dp
import com.example.myapp.App
fun main() = application {
Window(
onCloseRequest = ::exitApplication,
title = "Compose Multiplatform App",
state = rememberWindowState(width = 800.dp, height = 600.dp)
) {
App()
}
}馃煩 12. Settings Gradle
馃搫 settings.gradle.kts
pluginManagement {
repositories {
google()
gradlePluginPortal()
mavenCentral()
}
}
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}
rootProject.name = "MyComposeApp"
include(":androidApp")
include(":desktopApp")
include(":common")馃煩 13. Ejecutar las Aplicaciones
Android
./gradlew :androidApp:installDebugDesktop
./gradlew :desktopApp:runCrear Ejecutable Desktop
./gradlew :desktopApp:createDistributable馃煩 14. Recursos por Plataforma
// En commonMain
expect fun loadImage(): ImageBitmap
// En androidMain
actual fun loadImage(): ImageBitmap {
// Cargar desde recursos Android
}
// En desktopMain
actual fun loadImage(): ImageBitmap {
// Cargar desde recursos Desktop
}馃煩 15. Ventajas y Desventajas
Ventajas
✓ C贸digo compartido (50-90%)
✓ UI consistente
✓ Desarrollo m谩s r谩pido
✓ Mantenimiento simplificado
✓ Nativo en todas las plataformas
Desventajas
✗ Curva de aprendizaje
✗ iOS a煤n experimental
✗ Menos recursos que Flutter
✗ Requiere conocimiento de Kotlin
馃煩 16. Comparaci贸n con Flutter
| Caracter铆stica | Compose MP | Flutter |
|---|---|---|
| Lenguaje | Kotlin | Dart |
| Madurez | Creciendo | Maduro |
| Rendimiento | Nativo | Cerca de nativo |
| Android | Excelente | Muy bueno |
| iOS | Experimental | Excelente |
| Desktop | Estable | Estable |
| Comunidad | Media | Grande |
▶️ C贸mo Ejecutar
- Descarga IntelliJ IDEA
- Crea proyecto Kotlin Multiplatform
- Agrega dependencias Compose
- Copia el c贸digo
- Ejecuta para Android o Desktop
馃И Resultado Final
Aplicaci贸n funcionando en Android y Desktop con c贸digo compartido al 80-90%.
馃摜 Descargar Proyecto
馃憠
馃檶 Gracias por Visitar mi Blog
✔️ Comp谩rtelo
✔️ D茅jame un comentario
✔️ S铆gueme para m谩s contenido
❓ Preguntas Frecuentes
1. ¿Qu茅 es Compose Multiplatform?
Framework que permite crear apps para m煤ltiples plataformas compartiendo c贸digo UI y l贸gica.
2. ¿Es mejor que Flutter?
Depende. Compose es mejor para devs Android/Kotlin. Flutter tiene m谩s madurez y comunidad.
3. ¿Funciona en iOS?
S铆, pero a煤n es experimental. Se recomienda para producci贸n solo Android y Desktop.
4. ¿Cu谩nto c贸digo puedo compartir?
Entre 70-90% del c贸digo puede ser compartido entre plataformas.

No hay comentarios:
Publicar un comentario