A API Navigation Compose permite navegar entre elementos combináveis em um app do Compose, aproveitando o componente, a infraestrutura e os recursos do Jetpack Navigation.
Esta página descreve como migrar de uma navegação do Jetpack baseada em fragmentos para o Navigation Compose, como parte da migração maior da interface baseada em visualização para o Jetpack Compose.
Pré-requisitos de migração
É possível migrar para o Navigation Compose quando você conseguir substituir todos os fragmentos por elementos combináveis de tela correspondentes. Os elementos combináveis da tela podem conter uma mistura de conteúdo do Compose e da View, mas todos os destinos de navegação precisam ser elementos combináveis para permitir a migração do Navigation Compose. Até lá, continue usando o componente de navegação baseado em fragmentos na sua base de código de interoperabilidade do View e do Compose. Consulte a documentação de interoperabilidade de navegação para mais informações.
Não é necessário usar o Navigation Compose em um app somente com Compose. Você pode continuar usando o componente de navegação baseado em fragmentos, desde que mantenha os fragmentos para hospedar seu conteúdo combinável.
Etapas da migração
Se você estiver seguindo nossa estratégia de migração recomendada ou adotando outra abordagem, vai chegar a um ponto em que todos os destinos de navegação serão composições de tela, com os fragmentos atuando apenas como contêineres combináveis. Nesta etapa, você pode migrar para o Navigation Compose.
Se o app já seguir um padrão de design UDF e nosso guia de arquitetura, a migração para o Jetpack Compose e o Navigation Compose não vai exigir grandes refatorações de outras camadas do app, além da camada de UI.
Para migrar para o Navigation Compose, siga estas etapas:
- Adicione a dependência do Navigation Compose ao seu app.
Crie um elemento combinável
App-level
e adicione-o aoActivity
como ponto de entrada do Compose, substituindo a configuração do layout da View:class SampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample) setContent { SampleApp(/* ... */) } } }
Crie tipos para cada destino de navegação. Use um
data object
para destinos que não exigem dados edata class
ouclass
para destinos que exigem dados.@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
Configure o
NavController
em um local em que todos os elementos combináveis que precisam referenciá-lo tenham acesso a ele (geralmente dentro do elemento combinávelApp
). Essa abordagem segue os princípios da elevação de estado e permite usar oNavController
como a fonte da verdade para navegar entre telas combináveis e manter a backstack:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
Crie o
NavHost
do app dentro do elemento combinávelApp
e transmita onavController
:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
Adicione os destinos
composable
para criar seu gráfico de navegação. Se cada tela já tiver sido migrada para o Compose, esta etapa consistirá apenas em extrair esses elementos combináveis de tela dos seus fragmentos para os destinoscomposable
:class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { // FirstScreen(...) EXTRACT FROM HERE } } } } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen(/* ... */) // EXTRACT TO HERE } composable<Second> { SecondScreen(/* ... */) } // ... } }
Se você seguiu as orientações sobre arquitetura da sua interface do Compose, especificamente como
ViewModel
s e eventos de navegação devem ser transmitidos para combináveis, a próxima etapa é mudar a forma como você fornece oViewModel
para cada elemento combinável de tela. Muitas vezes, é possível usar a injeção do Hilt e o ponto de integração dele com o Compose e a Navigation viahiltViewModel
:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
Substitua todas as chamadas de navegação
findNavController()
pelasnavController
e transmita-as como eventos de navegação para cada tela combinável, em vez de transmitir todo onavController
. Essa abordagem segue as práticas recomendadas de expor eventos de funções combináveis para chamadores e mantém onavController
como a única fonte de verdade.Os dados podem ser transmitidos para um destino criando uma instância da classe de rota definida para ele. Ele pode ser obtido diretamente da entrada da backstack no destino ou de um
ViewModel
usandoSavedStateHandle.toRoute()
.@Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen( onButtonClick = { // findNavController().navigate(firstScreenToSecondScreenAction) navController.navigate(Second(id = "ABC")) } ) } composable<Second> { backStackEntry -> val secondRoute = backStackEntry.toRoute<Second>() SecondScreen( id = secondRoute.id, onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate(Third) } ) } // ... } }
Remova todos os fragmentos, layouts XML relevantes, navegação desnecessária e outros recursos, além de dependências obsoletas de fragmentos e do Jetpack Navigation.
Encontre as mesmas etapas com mais detalhes relacionados ao Navigation Compose na documentação de configuração.
Casos de uso comuns
Não importa qual componente de navegação você esteja usando, os mesmos princípios de navegação se aplicam.
Confira alguns casos de uso comuns ao migrar:
- Navegar até um elemento combinável
- Navegar com argumentos
- Links diretos
- Navegação aninhada
- Integração com a barra de navegação inferior
- Integração com um componente de navegação personalizado
Para mais informações sobre esses casos de uso, consulte Navegação com Compose.
Recuperar dados complexos durante a navegação
É altamente recomendável não transmitir objetos de dados complexos ao navegar. Em vez disso, transmita as informações mínimas necessárias, como um identificador exclusivo ou outra forma de ID, como argumentos ao executar ações de navegação. Você precisa armazenar objetos complexos como dados em uma única fonte de verdade, como a camada de dados. Para mais informações, consulte Como recuperar dados complexos durante a navegação.
Se os fragmentos estiverem transmitindo objetos complexos como argumentos, refatore o código primeiro, de forma que permita armazenar e buscar esses objetos da camada de dados. Confira exemplos no repositório Now in Android.
Limitações
Esta seção descreve as limitações atuais do Navigation Compose.
Migração incremental para o Navigation Compose
No momento, não é possível usar o Navigation Compose e os fragmentos como destinos no seu código. Para começar a usar o Navigation Compose, todos os seus destinos precisam ser combináveis. Você pode acompanhar essa solicitação de recurso no Issue Tracker.
Animações de transição
A partir do Navigation 2.7.0-alpha01, o suporte para definir transições personalizadas, antes do AnimatedNavHost
, agora é compatível diretamente com o NavHost
. Leia as notas da versão para mais informações.
Saiba mais
Para mais informações sobre a migração para o Navigation Compose, consulte os seguintes recursos:
- Codelab do Navigation Compose: aprenda os conceitos básicos do Navigation Compose com um codelab prático.
- Repositório Now in Android: um app Android totalmente funcional criado inteiramente com Kotlin e Jetpack Compose, que segue as práticas recomendadas de design e desenvolvimento do Android e inclui o Navigation Compose.
- Migração do Sunflower para o Jetpack Compose: uma postagem do blog que documenta a jornada de migração do app de exemplo Sunflower das visualizações para o Compose, que também inclui a migração para o Navigation Compose.
- Jetnews para cada tela: uma postagem no blog que documenta a refatoração e migração da amostra do Jetnews para oferecer suporte a todas as telas com Jetpack Compose e Navigation Compose.
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Como navegar com o Compose
- Compose e outras bibliotecas
- Outras considerações