Voyager: Navegação Multiplataforma e ViewModels (ScreenModel)
Intro
Projetado para Jetpack Compose, o Voyager simplifica a navegação e o gerenciamento de viewModels (screenModel) em várias plataformas. Neste artigo, vamos explorar os princípios fundamentais do Voyager, suas características e como ele remodela o desenvolvimento de interfaces de usuário em kotlin multiplataform.
Configuração
Voyager fornece múltiplas dependências conforme sua necessidade, cada uma com uma funcionalidade:
dependencies {
val voyagerVersion = "1.0.0"
// Multiplatform
// Navigator
implementation("cafe.adriel.voyager:voyager-navigator:$voyagerVersion")
// Screen Model
implementation("cafe.adriel.voyager:voyager-screenmodel:$voyagerVersion")
// BottomSheetNavigator
implementation("cafe.adriel.voyager:voyager-bottom-sheet-navigator:$voyagerVersion")
// TabNavigator
implementation("cafe.adriel.voyager:voyager-tab-navigator:$voyagerVersion")
// Transitions
implementation("cafe.adriel.voyager:voyager-transitions:$voyagerVersion")
// Android
// Koin integration
implementation("cafe.adriel.voyager:voyager-koin:$voyagerVersion")
// Hilt integration
implementation("cafe.adriel.voyager:voyager-hilt:$voyagerVersion")
// LiveData integration
implementation("cafe.adriel.voyager:voyager-livedata:$voyagerVersion")
// Desktop + Android
// Kodein integration
implementation("cafe.adriel.voyager:voyager-kodein:$voyagerVersion")
// RxJava integration
implementation("cafe.adriel.voyager:voyager-rxjava:$voyagerVersion")
}
Para este tutorial, vamos utilizar o Navigator
e o ScreenModel
, então podemos começar adicionando essas implementações ao nosso arquivo de catálogo de versões:
[versions]
voyager = "1.0.0"
[libraries]
voyager-navigator = { module = "cafe.adriel.voyager:voyager-navigator", version.ref = "voyager" }
voyager-screenModel = { module = "cafe.adriel.voyager:voyager-screenmodel", version.ref = "voyager" }
Agora vamos importar essas novas bibliotecas no nosso arquivo build.gradle
do Compose:
commonMain.dependencies {
implementation(libs.voyager)
implementation(libs.voyager.screenModel)
}
Entendendo ScreenModel e ViewModel
ScreenModel
é semelhante a uma ViewModel
: projetado para armazenar e gerenciar dados relacionados à interface do usuário de forma consciente no ciclo de vida. Também permite que os dados sobrevivam a mudanças de configuração, como rotações de tela. (Documentação do Voyager)
Com isso em mente, vamos criar um ScreenModel
simples para buscar alguns dados:
import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.screenModelScope
class DataScreenModel() : ScreenModel {
fun fetchData(){
screenModelScope.launch {
//fetch data code
}
}
}
Note que estamos usando screenModelScope
em vez de viewModelScope
, mas eles se comportam de forma semelhante.
Isso é tudo, esta é uma implementação simples de um screenModel
.
Navegando Telas
Primeiro, vamos envolver nosso composable principal por um Navigator
e, no construtor, passar a primeira tela que queremos exibir, neste caso será DataScreen
.
import cafe.adriel.voyager.navigator.Navigator
@Composable
fun App() {
Navigator(DataScreen())
}
Agora, vamos criar nossa DataScreen
implementando a interface Screen
e substituindo a função content
(isso será exibido na tela). Além disso, nesta tela queremos navegar para outra tela. Para fazer isso, queremos importar o LocalNavigator
e chamar a função push
para empurrar uma nova tela passando os parâmetros necessários.
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator
class DataScreen : Screen {
@Composable
override fun Content {
val navigator = LocalNavigator.currentOrThrow
// em um clique de botão ou evento chamar :
navigator.push(DataDetailsScreen(data))
}
}
Para obter os parâmetros, nossa segunda tela será uma data class
. Este será o resultado:
import cafe.adriel.voyager.core.screen.Screen
data class DataDetailScreen(data : Data) : Screen {
@Composable
override fun Content {
// mostrar dados no composable
// em um clique de botão ou evento chamar :
navigator.pop()
}
}
Se desejar voltar à tela anterior, use a função navigator.pop()
.
Transições
Se você quiser adicionar transições a este navigator
, primeiro precisamos adicionar a dependência de transições.
[versions]
voyager = "1.0.0"
[libraries]
voyager-transitions = { module = "cafe.adriel.voyager:voyager-transitions", version.ref = "voyager" }
commonMain.dependencies {
implementation(libs.voyager.transitions)
}
Agora vamos aplicar a transição no componente Navigator no Composable do aplicativo:
@Composable
fun App() {
Navigator(DataScreen()) { navigator ->
SlideTransition(navigator)
}
}
Neste caso, estamos usando a SlideTransition
. Para ver as transições disponíveis, consulte a documentação.
É isso! Esta é uma implementação simples do Voyager. Tenha em mente que existem múltiplas implementações e suporte para Koin, Hilt, Codein, etc. Esta é uma biblioteca muito bem documentada, então visite a documentação para mais detalhes.