Creación de pantalla de previsualización de fotos con Jetpack Compose
Clase 28 de 33 • Curso de Android: Integración de APIs nativas
Contenido del curso
- 7

Emisión controlada de tiempo con Kotlin Flows
12:55 - 8

Simulación de ubicación GPS en emulador y dispositivo Android
05:48 - 9

Modelos de localización personalizados con Clean Architecture en Kotlin
08:36 - 10

Mapeo de datos de localización en Android con Kotlin
14:51 - 11

Inyección de dependencias para observar localización en Android
06:33 - 12

StateFlow para controlar localización en aplicaciones Android
08:47 - 13

State Flows para controlar localización y tiempo en Kotlin
10:00 - 14

Configuración y pruebas de Location Tracker en Android
09:37 quiz de Servicios de Localización
- 15

Integración de ubicación actual en mapas interactivos
06:46 - 16

Creación de polilíneas con datos reales en mapas de Android
04:07 - 17

Integración de intents y estados en pantalla mapa con Compose
08:05 - 18

Implementación del ViewModel para rastreo de localización en Android
14:29 quiz de Integración Maps con Localización
- 19

Gestión de permisos en tiempo de ejecución para aplicaciones Android
08:34 - 20

Creación de diálogos de permisos reutilizables en Android
06:55 - 21

Gestión de permisos de localización y notificaciones en Android
10:18 - 22

Implementación de solicitud de permisos con LaunchedEffect en Compose
09:53 quiz de Manejo de permisos
- 23

Implementación de PhotoHandler para gestión de cámara en Android
11:59 - 24

Conversión de Bitmaps a Byte Arrays con Extension Functions
05:58 - 25

Definición de Intents y estados de UI para cámara en Kotlin
08:41 - 26

Configuración de métodos del ViewModel para gestión de cámara
09:41 - 27

Integración de CameraX con Jetpack Compose en Android
14:23 - 28

Creación de pantalla de previsualización de fotos con Jetpack Compose
08:44 - 29

Integración de galería fotográfica en mapas con Jetpack Compose
11:56 quiz de Integración cámara
Desarrollar una aplicación para Android eficiente y amigable implica aprovechar al máximo las capacidades que ofrece Jetpack Compose. Uno de los procesos fundamentales es darle al usuario la opción de previsualizar una imagen después de haberla capturado, ofreciéndole la alternativa de guardar o cancelar dicha acción. Dominar este procedimiento permite crear una interfaz fluida y centrada en la experiencia del usuario.
¿Cómo preparar la pantalla de previsualización con Jetpack Compose?
Preparar una pantalla de previsualización sencilla y eficaz requiere utilizar Composables específicos. Para comenzar, se crea un Composable denominado photo preview screen, el cual recibe:
- Un arreglo de bytes (byte array) que representa la imagen tomada.
- Dos funciones lambda: una acción llamada
onSavepara guardar la foto y una acciónonCancelpara descartarla.
Esta vista incluye:
- Una columna que contiene un Box, mostrando la imagen previamente convertida a Image bitmap usando una extensión creada.
- Un Row que alberga dos íconos claramente identificables, uno para cancelar y otro para guardar la imagen mostrada.
Toda esta configuración facilita que el usuario tome decisiones rápidas e intuitivas sobre qué hacer con su imagen recién capturada.
¿Cómo gestionar el estado desde el ViewModel?
La manera óptima para manejar la información y la interacción con la UI es utilizando un ViewModel en combinación con un estado observable:
- Obtén el estado del ViewModel a través de
collectAsState, observando la disponibilidad de la imagen tomada. - Según el estado del ViewModel y la disponibilidad del preview, se muestra la pantalla con la imagen capturada o la pantalla de la cámara.
Ejemplo práctico de cómo invocar la pantalla de previsualización:
val uiState by viewModel.uiState.collectAsState()
val previewPhoto by viewModel.previewPhoto.collectAsState()
if(uiState.previewMode && previewPhoto != null){
PhotoPreviewScreen(
photoBytes = previewPhoto,
onSave = { viewModel.action(Intent.SavePhoto) },
onCancel = { viewModel.action(Intent.CancelPreview) }
)
}else{
CameraScreen(onPhotoTaken = { imageProxy ->
// Lógica para rotar imagen aquí
})
}
Esta estructura clara asegura que siempre se visualice la pantalla correcta, mejorando significativamente la usabilidad.
¿Cómo rotar correctamente las imágenes capturadas?
La rotación es un proceso crítico para reflejar correctamente las imágenes capturadas desde la cámara. Dado que la imagen inicialmente llega en orientación de 90 grados, debe realizarse un ajuste utilizando una matriz de rotación:
- Se extrae la rotación directa desde
imageProxy.imageInfo.rotationDegrees. - Se crea un bitmap rotado usando una matriz para ajustar apropiadamente la imagen capturada.
Código de ejemplo para rotar la imagen correctamente:
val matrix = Matrix().apply{
postRotate(imageProxy.imageInfo.rotationDegrees.toFloat())
}
val rotatedBitmap = imageProxy.toBitmap().let{
Bitmap.createBitmap(it,0,0,it.width,it.height,matrix,true)
}
viewModel.action(CameraIntent.TakingPicture(rotatedBitmap))
Siguiendo estos pasos, aseguras que las fotos capturadas se visualicen correctamente desde cualquier dispositivo Android.
Integración en la navegación de la aplicación
La pantalla de captura y previsualización debe estar cuidadosamente integrada en la configuración principal de navegación:
- Reemplaza la pantalla previa de cámara (
cameraScreen) por la nueva creada (cameraScreenRoot). - Valida mediante el emulador que todo sea funcional, permitiendo tanto la captura como la revisión de fotos.
Recuerda que estos ajustes son elementales para garantizar que la navegación cumpla con las expectativas del usuario y el estándar de desarrollo actual.
Reto adicional para practicar: No olvides realizar el proceso de solicitud de permisos como lo realizaste anteriormente con la pantalla MapScreen, verificando los detalles del repositorio si tienes dudas sobre esta implementación. ¡Ánimo!