Esta página é um guia para modularizar seu código de navegação. Ele complementa a orientação geral para modularização de apps.
Visão geral
A modularização do código de navegação é o processo de separação de chaves de navegação relacionadas e do conteúdo que elas representam em módulos individuais. Isso oferece uma separação clara de responsabilidades e permite navegar entre diferentes recursos no app.
Para modularizar seu código de navegação, faça o seguinte:
- Crie dois submódulos:
apieimplpara cada recurso no app. - Coloque as chaves de navegação de cada recurso no módulo
api. - Coloque
entryProviderse o conteúdo navegável de cada recurso no móduloimplassociado. - Forneça
entryProvidersaos módulos principais do app, diretamente ou usando injeção de dependência
Separar recursos em submódulos de API e implementação
Para cada recurso no app, crie dois submódulos chamados api e impl
(abreviação de "implementação"). Use a tabela a seguir para decidir onde colocar o código de navegação.
Nome do módulo |
Contém |
|
|
|
Conteúdo desse recurso, incluindo definições de |
Essa abordagem permite que um recurso navegue para outro, permitindo que o conteúdo dele,
contido no módulo impl, dependa das chaves de navegação de outro
módulo, contido no módulo api desse módulo.
Separar entradas de navegação usando funções de extensão
Na Navegação 3, o conteúdo navegável é definido usando entradas de navegação. Para
separar essas entradas em módulos diferentes, crie funções de extensão em
EntryProviderScope e mova-as para o módulo impl desse recurso.
Eles são conhecidos como criadores de entradas.
O exemplo de código a seguir mostra um criador de entradas que cria duas entradas de navegação.
// import androidx.navigation3.runtime.EntryProviderScope // import androidx.navigation3.runtime.NavKey fun EntryProviderScope<NavKey>.featureAEntryBuilder() { entry<KeyA> { ContentRed("Screen A") { // Content for screen A } } entry<KeyA2> { ContentGreen("Screen A2") { // Content for screen A2 } } }
Chame essa função usando a DSL entryProvider ao definir seu
entryProvider no módulo principal do app.
// import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay NavDisplay( entryProvider = entryProvider { featureAEntryBuilder() }, // ... )
Usar a injeção de dependência para adicionar entradas ao app principal
No exemplo de código anterior, cada criador de entradas é chamado diretamente pelo app principal
usando a DSL entryProvider. Se o app tiver muitas telas ou módulos de
recursos, isso pode não ser escalonável.
Para resolver isso, faça com que cada módulo de recurso contribua com os criadores de entradas na atividade do app usando a injeção de dependência.
Por exemplo, o código a seguir usa multibindings do Dagger,
especificamente @IntoSet, para injetar os criadores de entradas em um Set pertencente a
MainActivity. Elas são chamadas de forma iterativa dentro de entryProvider, eliminando a necessidade de chamar explicitamente várias funções de criador de entradas.
Módulo do recurso
// import dagger.Module // import dagger.Provides // import dagger.hilt.InstallIn // import dagger.hilt.android.components.ActivityRetainedComponent // import dagger.multibindings.IntoSet @Module @InstallIn(ActivityRetainedComponent::class) object FeatureAModule { @IntoSet @Provides fun provideFeatureAEntryBuilder() : EntryProviderScope<NavKey>.() -> Unit = { featureAEntryBuilder() } }
Módulo de app
// import android.os.Bundle // import androidx.activity.ComponentActivity // import androidx.activity.compose.setContent // import androidx.navigation3.runtime.EntryProviderScope // import androidx.navigation3.runtime.NavKey // import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay // import javax.inject.Inject class MainActivity : ComponentActivity() { @Inject lateinit var entryBuilders: Set<@JvmSuppressWildcards EntryProviderScope<NavKey>.() -> Unit> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { NavDisplay( entryProvider = entryProvider { entryBuilders.forEach { builder -> this.builder() } }, // ... ) } } }
Se as entradas de navegação precisarem navegar (por exemplo, se contiverem elementos da interface que navegam para novas telas), injete um objeto capaz de modificar o estado de navegação do app em cada função de builder.
Recursos
Para exemplos de código que mostram como modularizar o código do Navigation 3, consulte:
- Receitas de código da arquitetura Navigation 3
- Jornada de aprendizado sobre modularização do app Now in Android
- Androidify