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 de interface maior baseada em visualização para o Jetpack Compose.
Pré-requisitos de migração
Você pode migrar para o Navigation Compose quando puder substituir todos os fragmentos pelos elementos combináveis de tela correspondentes. Os elementos combináveis da tela podem conter um mix de conteúdo do Compose e da View, mas todos os destinos de navegação precisam ser combináveis para ativar a migração do Compose de navegação. Até lá, continue usando o componente de navegação baseado em fragmentos na sua base de código de interoperabilidade de visualizações e do Compose. Consulte a documentação de interoperabilidade de navegação para mais informações.
O uso do Navigation Compose em um app exclusivo do Compose não é um pré-requisito. Você pode continuar usando o componente de navegação baseado em fragmentos, desde que mantenha fragmentos para hospedar seu conteúdo combinável.
Etapas da migração
Se você estiver seguindo nossa estratégia de migração recomendada ou usando outra abordagem, vai chegar a um ponto em que todos os destinos de navegação serão combináveis de tela, com fragmentos atuando apenas como contêineres combináveis. Nesta etapa, você pode migrar para o Navigation Compose.
Se o app já estiver seguindo 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 refatorações importantes de outras camadas do app, além da camada de interface.
Para migrar para o Navigation Compose, siga estas etapas:
- Adicione a dependência de navegação do Compose ao app.
Crie um elemento combinável
App-level
e adicione-o aoActivity
como ponto de entrada do Compose, substituindo a configuração do layout de visualização: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
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 referenciar tenham acesso a ele (geralmente dentro do elemento combinávelApp
). Essa abordagem segue os princípios da elevação de estado e permite que você use 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 o gráfico de navegação. Se cada tela foi migrada anteriormente para o Compose, essa etapa consiste apenas em extrair esses elementos combináveis de tela dos 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 como projetar a interface do Compose, especificamente como
ViewModel
s e eventos de navegação precisam 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 com o Compose e a Navigation usandohiltViewModel
:@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 onavController
inteiro. Essa abordagem segue as práticas recomendadas para expor eventos de funções combináveis aos autores de chamada 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 esse destino. 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 de fragmento e navegação do Jetpack desaturadas.
Confira 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ê está usando, os mesmos princípios de navegação se aplicam.
Os casos de uso comuns ao migrar incluem:
- 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 informações mais detalhadas sobre esses casos de uso, consulte Navegar com o Compose.
Extrair 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. É necessário armazenar objetos complexos como dados em uma única fonte da 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 uma maneira que permita armazenar e buscar esses objetos da camada de dados. Confira exemplos no repositório do 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 enquanto você ainda usa fragmentos como destinos no código. Para começar a usar o Navigation Compose, todos os destinos precisam ser combináveis. É possível acompanhar essa solicitação de recurso no Issue Tracker.
Animações de transição
A partir da Navigation 2.7.0-alpha01, o suporte para definir transições
personalizadas, anteriormente de AnimatedNavHost
, agora é
oferecido diretamente no NavHost
. Leia as notas da versão para
mais informações.
Saiba mais
Para mais informações sobre como migrar para o Navigation Compose, consulte os seguintes recursos:
- Codelab de 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 com o Kotlin e o Jetpack Compose, que segue as práticas recomendadas de design e desenvolvimento do Android e inclui o Navigation Compose.
- Como migrar o Sunflower para o Jetpack Compose: uma postagem do blog que documenta a jornada de migração do app de exemplo Sunflower de visualizações para o Compose, que também inclui a migração para o Navigation Compose.
- Jetnews para cada tela: uma postagem de blog que documenta a refatoração e migração do exemplo do Jetnews para oferecer suporte a todas as telas com o Jetpack Compose e o 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