4.5 Imágenes en Compose Multiplatform¶
Si tu proyecto es multiplataforma (por ejemplo, el creado con el asistente de JetBrains), las imágenes no van en res/drawable.
Paso a paso¶
- Copia las imágenes (por ejemplo
foto1.png,foto2.png,foto3.png) en:
shared/src/commonMain/composeResources/drawable/
Nombres en minúsculas, sin espacios, guiones ni tildes.
2. Reconstruye el proyecto: Build → Rebuild Project. Se genera la clase Res con un acceso por imagen: Res.drawable.foto1, Res.drawable.foto2…
3. Úsalas con Image y painterResource:
import org.jetbrains.compose.resources.painterResource
// y los imports de Res y de cada imagen (Alt+Enter los añade)
@Composable
fun Galeria() {
Image(
painter = painterResource(Res.drawable.foto1),
contentDescription = "Foto 1 de la galería",
modifier = Modifier.size(240.dp)
)
}
Errores típicos
- Unresolved reference
Res: no has reconstruido el proyecto o el archivo está en el módulo equivocado (debe estar enshared). - Unresolved reference
foto1: el archivo tiene un nombre no válido o falta elimportde la imagen.
Mostrar y ocultar¶
Se guarda en una variable de estado si la imagen es visible y un if decide qué dibujar:
var visible by remember { mutableStateOf(true) }
if (visible) {
Image(painterResource(Res.drawable.foto1), contentDescription = "Foto", modifier = Modifier.size(240.dp))
} else {
Text("(imagen oculta)")
}
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
Button(onClick = { visible = true }) { Text("Mostrar") }
Button(onClick = { visible = false }) { Text("Ocultar") }
Button(onClick = { visible = !visible }) { Text(if (visible) "Ocultar" else "Mostrar") } // alternar
}
El tercer botón es un interruptor (toggle): invierte el valor y, como el texto depende del estado, su etiqueta cambia sola.
Una galería con selector¶
Se guarda qué foto se muestra y un when elige el recurso:
var actual by remember { mutableIntStateOf(1) }
val foto = when (actual) {
1 -> Res.drawable.foto1
2 -> Res.drawable.foto2
else -> Res.drawable.foto3
}
Image(painterResource(foto), contentDescription = "Foto $actual de la galería", modifier = Modifier.size(240.dp))
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
Button(onClick = { actual = 1 }) { Text("Foto 1") }
Button(onClick = { actual = 2 }) { Text("Foto 2") }
Button(onClick = { actual = 3 }) { Text("Foto 3") }
}
mutableIntStateOf es una versión de mutableStateOf pensada para enteros: evita convertir el número a objeto y es un poco más eficiente.