Una biblioteca de navegación pequeña y simple, pero completa y personalizable para Esfera de mochila propulsora:
- Completo Tipo de seguridad
- restauración del estado
- Navegación anidada con backstacks independientes
- Usted posee el ciclo de vida, el estado guardado y las plantillas de vista para cada entrada de backstack
- Transiciones animadas
- La lógica de navegación se puede mover fácilmente a la capa ViewModel
- Sin constructores, sin superclases obligatorias para tus componibles
- Se puede utilizar para la gestión de diálogos.
Para comenzar
Agregue una sola dependencia a su proyecto:
implementation("dev.olshevski.navigation:reimagined:1.0.0-beta01")
Defina un conjunto de pantallas, por ejemplo, como una clase sellada:
sealed class Screen : Parcelable {
@Parcelize
object First : Screen()
@Parcelize
data class Second(val id: Int) : Screen()
@Parcelize
data class Third(val text: String) : Screen()
}
Crear un modular con NavController
Y NavHost
:
@Composable
fun NavHostScreen() {
val navController = rememberNavController<Screen>(
startDestination = Screen.First,
)
NavBackHandler(navController)
NavHost(controller = navController) { screen ->
when (screen) {
Screen.First -> Column {
Text("First screen")
Button(onClick = {
navController.navigate(Screen.Second(id = 42))
}) {
Text("To Second screen")
}
}
is Screen.Second -> Column {
Text("Second screen: ${screen.id}")
Button(onClick = {
navController.navigate(Screen.Third(text = "Hello"))
}) {
Text("To Third screen")
}
}
is Screen.Third -> {
Text("Third screen: ${screen.text}")
}
}
}
}
Como puedes ver, NavController
se utiliza para cambiar entre pantallas, NavBackHandler
gestiona las prensas traseras e NavHost
simplemente proporciona un componible correspondiente al último destino en el backstack. Tan sencillo.
Lo esencial
Aquí está el flujo de trabajo general de la biblioteca:
Vamos a entrar en detalle en cada uno de ellos.
controlador de navegación
Este es el principal punto de control de navegación. Realiza un seguimiento de todas las entradas backstack actuales y las mantiene en actividades/recreación de procesos.
NavController se puede crear con rememberNavController
dentro de la composición o con navController
fuera de ella Este último se puede usar para almacenar NavController en un ViewModel. Dado que implementa la interfaz Parcelable, podría (y debería) almacenarse en Manejador de estado guardado.
Ambos rememberNavController
Y navController
los métodos aceptan startDestination
como parámetro. Si desea crear NavController con un número arbitrario de elementos backstack, puede usar initialBackstack
parámetro en su lugar.
Destinos
NavController acepta todos los tipos que cumplen los requisitos como objetivos. Los requisitos son:
-
El tipo debe ser Parcelable, Serializable o primitivo o cualquier otro tipo en el que se pueda escribir Paquete.
-
El tipo debe ser uno de los dos Estableo Inmutableo primitivo.
Métodos de navegación
Hay un puñado de métodos predefinidos adecuados para la navegación básica de aplicaciones: navigate
, pop
, popUpTo
, popAll
, replaceLast
, replaceUpTo
, replaceAll
. Todos son bastante autoexplicativos.
Si su caso de uso requiere alguna manipulación avanzada de backstack, puede usarlo setNewBackstackEntries
método. De hecho, este es el único método público definido en NavController, todos los demás métodos se proporcionan como extensiones y uso setNewBackstackEntries
bajo el capó. Puede verlo como un nuevo método de extensión navigateToTab
se implementa en el muestra.
NavBackstack
Esta es una clase de solo lectura que puede usar para acceder a las entradas actuales de backstack y la última NavAction. Las propiedades son compatibles con estado mutableentonces Compose será notificado de los cambios.
Si desea escuchar los cambios de backstack fuera de la composición, puede configurar onBackstackChange
oyente en NavController.
Anfitrión de navegación
NavHost es un complemento que muestra la última entrada en un backstack y proporciona todos los componentes asociados con esta entrada en particular: Ciclo vital, Registro de estado guardado Y VerModeloTienda. Todos estos componentes se suministran a través de ComposiciónLocalProvider dentro de sus respectivos dueños LocalLifecycleOwner
, LocalSavedStateRegistryOwner
Y LocalViewModelStoreOwner
.
Los componentes se retienen hasta que la entrada asociada se elimine del backstack (o hasta que se elimine la entrada principal que contiene el NavHost secundario actual).
NavHost en sí mismo no proporciona transiciones animadas, simplemente salta al siguiente destino.
AnimatedNavHost
AnimatedNavHost incluye todas las funciones del NavHost normal, pero también admite transiciones animadas. La transición predeterminada es un fundido cruzado simple, pero puede personalizar granularmente cada transición con su propia transición. AnimatedNavHostTransitionSpec
implementación.
Aquí hay una posible implementación de AnimatedNavHostTransitionSpec:
val CustomTransitionSpec = AnimatedNavHostTransitionSpec<Any?> { action, from, to ->
val direction = if (action == NavAction.Pop) {
AnimatedContentScope.SlideDirection.End
} else {
AnimatedContentScope.SlideDirection.Start
}
slideIntoContainer(direction) with slideOutOfContainer(direction)
}
Configúralo en AnimatedNavHost:
AnimatedNavHost(
controller = navController,
transitionSpec = CustomTransitionSpec
) { destination ->
// ...
}
y terminará luciendo así:
En AnimatedNavHostTransitionSpec obtenga los parámetros:
action
– el consejo sobre el último método NavController que cambió el backstackfrom
– el destino visible anteriorto
– el objetivo visible del objetivo
Esta información es suficiente para elegir una transición para cada combinación posible de pantallas y acciones de navegación.
Acción de navegación
Hay cuatro tipos de NavAction predefinidos:
Pop
,Replace
YNavigate
– objetos a los que correspondenpop…
,replace…
,navigate
Métodos de NavControllerIdle
– la acción predeterminada de un NavController recién creado
También puede crear un nuevo tipo de acción extendiendo resumen NavAction
clase. Cambiar este nuevo tipo en setNewBackstackEntries
método de NavController y manejarlo en AnimatedNavHostTransitionSpec.
También se puede acceder a la última acción a través de action
propiedad de NavBackstack.
DialogNavHost
La versión de NavHost más adecuada para mostrar diálogos. Se basa en AnimatedNavHost y proporciona una transición más suave entre los diálogos sin scrim/fade.
Si desea ver cómo implementar la navegación en los cuadros de diálogo, explore el archivo muestra.
Tenga en cuenta que DialogNavHost no envuelve sus componibles en un cuadro de diálogo. Debe usar el uso de Dialog o Composable AlertDialog dentro de un contentSelector
tú mismo.
Gestión de la espalda
Volver a la administración de la biblioteca es optar por participar en lugar de optar por no participar. Por sí mismos, ni NavController ni NavHost manejan presionar el botón Atrás. puedes añadir NavBackHandler
o normales BackHandler
para reaccionar a las presiones traseras donde se necesita.
NavBackHandler es la implementación más simple de llamadas BackHandler pop
hasta que quede un artículo en la pila trasera. Luego se desactiva, por lo que cualquier BackHandler de nivel superior puede reaccionar al presionar el botón Atrás.
Nota IMPORTANTE: siempre coloque NavBackHandler / BackHandler antes de el NavHost correspondiente. Lee la explicación aquí.
Navegación anidada
Agregar navegación anidada es tan simple como colocar un NavHost en otro. Todo se maneja correctamente y funciona.
Puede ir a tantas capas en profundidad como desee. Y cómo fractalespero en la navegación.
Devuelve los valores a los destinos anteriores
Dado que los tipos de destino no necesariamente tienen que ser inmutables, puede cambiarlos mientras están apilados. Se puede utilizar para devolver valores de otros destinos. Simplemente cree una propiedad mutable compatible con mutableStateOf
y cambiarlo cuando sea necesario. Puede ver la demostración aquí.
Nota: Por lo general, devolver valores al destino anterior complica la lógica de navegación. Además, este enfoque no garantiza la seguridad del tipo en tiempo de compilación. Úselo con precaución y cuando esté seguro de lo que está haciendo. A veces puede ser más fácil usar un titular de estado compartido.
Documentación y muestra
Explore la documentación de KDoc de la biblioteca para obtener más detalles sobre cada componente y cada función admitida.
Además, explore la muestra. Proporciona demostraciones de todas las características mencionadas anteriormente y más. La muestra muestra:
- navegación anidada
- navegación por pestañas
- Usando NavHost / AnimatedNavHost
- diálogos
- pasar y devolver valores
- Ver plantillas
- elevando NavController al nivel de ViewModel
¿Por qué beta?
Estoy muy satisfecho con la forma y la forma de la librería. He pasado largas noches sin dormir depurando y puliendo todos los casos de esquina.
Por ahora, estaré encantado de recibir comentarios y realizar pequeños cambios en la API (si los hay). Si hay algún cambio, es posible que espere un aviso en las notas de la versión.
De
He estado pensando en la arquitectura y la navegación de las aplicaciones de Android en particular durante mucho tiempo. Cuando conocí Compose, finalmente pude crear la estructura de navegación que se adapta perfectamente a todas mis necesidades.
Hacerlo en forma de biblioteca pública cierra para mí una gestalt. Finalmente terminé. ¡Hacia nuevos proyectos!
Si le gusta esta biblioteca y la encuentra útil, agregue el proyecto a Destacado y compártalo con sus compañeros desarrolladores. Un poco de promoción nunca viene mal.