Trabajo avanzado con el snack bar en el Jetpack Compose | de Sergei Mijailovski | octubre 2022
La imagen proviene de material.ioIntroducciónHace unos días recibí la tarea: mostrar la barra de refrigerios si la llamada a la API terminó con el error, como InternalServiceError, BadGateway o NotFound. Prácticas recomendadas de implementación. El tutorial más útil fue este, ya que cubría completamente cómo mostrar una barra de bocadillos.Ahora es el momento de describir la arquitectura de la aplicación.El arco lateral de la interfaz de usuario se ve así:
- Estoy usando una arquitectura de actividad única (ya que está compuesta, es fácil seguir este principio)
- Mi aplicación Compose se ve así
- Las pantallas se muestran en NavHost, aquí hay un ejemplo de la pantalla que puede obtener el error del servidor
Como puede ver, el error que se suponía que debía mostrar al usuario proviene de ViewModel a través de SharedFlow.implementaciónPara mostrar la barra de bocadillos, debemos configurar ScaffoldState en Scaffold. ScaffoldState contiene 2 campos: DrawerState (ahora no nos interesa) y SnackbarHostState. Como dice la documentación:
SnackbarHostState: estado de SnackbarHost, controla la cola y la barra de bocadillos actual que se muestra dentro de SnackbarHost.
En el código se ve así: Y ahora nos enfrentamos al primer problema: nuestra pantalla (es decir, SplashScreen) no sabe nada sobre el estado del scaffold porque el scaffold se coloca en la raíz de la aplicación, no en el nivel de la pantalla. La primera solución que se me ocurrió es pasar el estado como parámetro a cualquier método componible que deba manejar la excepción. Pero esta solución no parece ser perfecta porque necesitamos pasar el estado a casi todos los componibles y, a veces, necesitamos pasarlo no porque nuestra función lo necesite, sino porque una función interna lo necesita. La segunda solución fue definir una variable global que mantuviera el estado y los componibles que necesitan mostrar un snackbar para acceder a él. Usé este enfoque pero lo modifiqué un poco. Aquí está el código: como puede ver, SnackbarDelegate es solo un contenedor sobre SnackbarHostState y CoroutineScope (necesitamos que muestre una barra de refrigerios ya que showSnackbar es una función de suspensión). El objeto de esta clase se registra como singleton en el contenedor DI, por lo que todas las clases y métodos que tienen acceso a este objeto funcionan con el mismo SnackbarHostState (el estado del esqueleto raíz SnackbarHost). Puede verlo en fragmentos de código a continuación). Y ahora nos enfrentamos al siguiente problema: diferentes estados de la barra de bocadillos. Por ejemplo, en mi aplicación hay 2 estados: error y snackbar predeterminado. La barra de bocadillos de error debe tener un fondo rojo, mientras que la barra de bocadillos predeterminada debe tener un color azul. Scaffold nos da la opción de personalizar un snackbar a través de un parámetro SnackbarHost. Nos permite mostrar cualquier componible como una barra de bocadillos, pero no sabe nada sobre los estados internos de nuestra barra de bocadillos. Resolví este problema con la ayuda de SnackbarDelegate. Aquí está la versión modificada. Hay varias diferencias entre esta versión y la anterior:
- He definido una variable que contiene el SnackbarState actual (el estado interno de mi aplicación).
- Antes de mostrar snackbar, guardo este estado (línea 26)
- Proporcionar un getter para un fondo de snack bar.
Y así es como se usa en el componible de la aplicación. Para usar el delegado, debe colocar el delegado en el componible y llamar al método showSnackbar. Aquí hay un ejemplo: en mi caso, agregué un intermediario: ErrorHandlerDelegate. Me permite manejar fácilmente los errores en toda la aplicación. Esta solución es escalable. Entonces, si necesito proporcionar algunos otros parámetros en Snackbar, puedo ponerlos en la clase de delegado y manejar su lógica dentro de la clase. ¡Y eso es!ConclusiónEn este artículo, describí una solución que permite trabajar con la barra de bocadillos en la gran aplicación Jetpack Compose y manejar sus diferentes estados. Puedes encontrar el código fuente en Github. ¡Gracias por leer! No dude en hacer preguntas y dejar sus comentarios en los comentarios o en Linkedin.