No momento da execução,
um FragmentManager
pode adicionar, remover, substituir e realizar outras ações com fragmentos
em resposta à interação do usuário. Cada conjunto de mudanças de fragmentos
confirmado é chamado de transação. É possível especificar o que será feito dentro
da transação usando as APIs fornecidas pela
classe
FragmentTransaction
. Você pode agrupar várias ações em uma única transação. Por exemplo, uma
transação pode adicionar ou substituir vários fragmentos. Esse agrupamento pode ser
útil quando há vários fragmentos irmãos exibidos na
mesma tela, como ocorre com visualizações divididas.
Também é possível salvar cada transação em uma pilha de retorno gerenciada pelo
FragmentManager
, permitindo que o usuário retorne para as
mudanças de fragmentos anteriores, de forma semelhante à navegação inversa pelas atividades.
É possível conseguir uma instância de FragmentTransaction
do FragmentManager
chamando beginTransaction()
, conforme mostrado no exemplo a seguir:
Kotlin
val fragmentManager = ... val fragmentTransaction = fragmentManager.beginTransaction()
Java
FragmentManager fragmentManager = ... FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
A chamada final em cada FragmentTransaction
precisa confirmar a transação.
A chamada commit()
indica ao FragmentManager
que todas as operações foram
adicionadas à transação.
Kotlin
val fragmentManager = ... // The fragment-ktx module provides a commit block that automatically // calls beginTransaction and commit for you. fragmentManager.commit { // Add operations here }
Java
FragmentManager fragmentManager = ... FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); // Add operations here fragmentTransaction.commit();
Permitir a reordenação de mudanças de estado do fragmento
Cada FragmentTransaction
precisa usar setReorderingAllowed(true)
:
Kotlin
supportFragmentManager.commit { ... setReorderingAllowed(true) }
Java
FragmentManager fragmentManager = ... fragmentManager.beginTransaction() ... .setReorderingAllowed(true) .commit();
Para compatibilidade de comportamento, a sinalização de reordenação não está ativada por padrão.
No entanto, é necessário permitir que FragmentManager
execute
a FragmentTransaction
de forma adequada, principalmente quando ele opera na pilha de retorno
e executa animações e transições. Ativar a sinalização garante que, se
várias transações forem executadas juntas, os fragmentos intermediários
(ou seja, aqueles que foram adicionados e substituídos imediatamente) não passarão por
mudanças de ciclo de vida nem terão animações ou transições executadas. Essa sinalização
afeta a execução inicial da transação e a reversão
da transação com popBackStack()
.
Adicionar e remover fragmentos
Para adicionar um fragmento a um FragmentManager
, chame
add()
na transação. Esse método recebe
o ID do contêiner do fragmento, assim como o nome da classe do
fragmento que você quer adicionar. O fragmento adicionado é movido para o estado
RESUMED
. É altamente recomendável que o contêiner seja
uma FragmentContainerView
que faça parte da hierarquia de visualização.
Para remover um fragmento do host, chame
remove()
,
transmitindo uma instância de fragmento que foi recuperada do gerenciador
de fragmentos por findFragmentById()
ou findFragmentByTag()
:
Se a visualização do fragmento tiver sido adicionada anteriormente a um contêiner, ela será
removida dele nesse momento. O fragmento removido é movido
para o estado DESTROYED
.
Use
replace()
para substituir um fragmento existente em um contêiner por uma instância de uma
nova classe de fragmentos fornecida. Chamar replace()
equivale a
chamar remove()
com fragmento em um contêiner e adicionar um novo
fragmento a esse mesmo contêiner.
O snippet de código a seguir mostra como substituir um fragmento por outro:
Kotlin
// Create new fragment val fragmentManager = // ... // Create and commit a new transaction fragmentManager.commit { setReorderingAllowed(true) // Replace whatever is in the fragment_container view with this fragment replace<ExampleFragment>(R.id.fragment_container) }
Java
// Create new fragment and transaction FragmentManager fragmentManager = ... FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.setReorderingAllowed(true); // Replace whatever is in the fragment_container view with this fragment transaction.replace(R.id.fragment_container, ExampleFragment.class, null); // Commit the transaction transaction.commit();
Nesse exemplo, uma nova instância de ExampleFragment
substitui o fragmento,
se houver, que está atualmente no contêiner de layout identificado por
R.id.fragment_container
.
Por padrão, as mudanças feitas em uma FragmentTransaction
não são adicionadas
à pilha de retorno. Para salvar essas mudanças, chame
addToBackStack()
na FragmentTransaction
. Para ver mais informações, consulte
Gerenciador de fragmentos.
A confirmação é assíncrona
Ao chamar
commit()
,
a transação não será realizada imediatamente. Em vez disso, a transação é
programada na principal linha de execução de IU para ser executada assim que possível. No entanto,
se necessário, você pode chamar
commitNow()
para executar a transação de fragmento imediatamente na linha de execução de IU.
commitNow
é incompatível com addToBackStack
. Como alternativa,
é possível executar todas as FragmentTransactions
pendentes enviadas por chamadas
commit()
que ainda não foram executadas, chamando executePendingTransactions()
. Essa abordagem é compatível com addToBackStack
.
Para a grande maioria dos casos de uso, você só precisa de commit()
.
A ordem da operação é importante
A ordem em que você realiza operações em uma
FragmentTransaction
é importante, especialmente ao usar setCustomAnimations()
. Esse
método aplica as animações fornecidas a todas as operações de fragmento
que o seguem.
Kotlin
supportFragmentManager.commit { setCustomAnimations(enter1, exit1, popEnter1, popExit1) add<ExampleFragment>(R.id.container) // gets the first animations setCustomAnimations(enter2, exit2, popEnter2, popExit2) add<ExampleFragment>(R.id.container) // gets the second animations }
Java
getSupportFragmentManager().beginTransaction() .setCustomAnimations(enter1, exit1, popEnter1, popExit1) .add(R.id.container, ExampleFragment.class, null) // gets the first animations .setCustomAnimations(enter2, exit2, popEnter2, popExit2) .add(R.id.container, ExampleFragment.class, null) // gets the second animations .commit()
Limitar o ciclo de vida do fragmento
As FragmentTransactions
podem afetar o estado do ciclo de vida de fragmentos
individuais adicionados ao escopo da transação. Ao criar uma
FragmentTransaction
,
setMaxLifecycle()
define um estado máximo para o fragmento especificado. Por exemplo,
ViewPager2
usa
setMaxLifecycle()
para limitar os fragmentos fora da tela ao estado STARTED
.
Como exibir e ocultar visualizações do fragmento
Use os métodos
show()
e
hide()
da FragmentTransaction
para exibir e ocultar a visualização de fragmentos que foram adicionados a um contêiner.
Esses métodos definem a visibilidade das visualizações do fragmento sem afetar
o ciclo de vida dele.
Embora não seja necessário usar uma transação de fragmento para alternar a visibilidade das visualizações em um fragmento, esses métodos são úteis para casos em que você quer que as mudanças no estado de visibilidade sejam associadas a transações na pilha de retorno.
Como anexar e remover fragmentos
O método detach()
da FragmentTransaction
separa o fragmento da IU, eliminando a hierarquia de visualização. O fragmento
permanece no mesmo estado (STOPPED
) quando é colocado na pilha de retorno.
Isso significa que o fragmento foi removido da IU, mas ainda é gerenciado pelo
gerenciador de fragmentos.
O
método attach()
anexa novamente um fragmento que já foi removido.
Isso faz com que a hierarquia de visualização seja recriada, anexada à IU
e exibida.
Como uma FragmentTransaction
é tratada como um único conjunto atômico de operações,
as chamadas para detach
e attach
na mesma instância de fragmento na
mesma transação cancelam efetivamente umas às outras, a fim de evitar a
destruição e a recriação imediata da IU do fragmento. Caso você queira
remover e, em seguida, imediatamente anexar mais uma vez um
fragmento, use transações separadas, divididas por executePendingOperations()
se estiver usando commit()
.