Qual é a diferença entre destacar um fragmento e removê-lo?

118

Na documentação do Android para uma FragmentTransaction , notei dois métodos muito semelhantes: detache remove. As descrições ali não parecem fornecer muitos insights sobre quando usar cada um e, pelo que posso dizer, eles parecem ser o mesmo.

Então: quais são as diferenças entre esses dois métodos?

yydl
fonte

Respostas:

156

O método detach remove o fragmento da IU, mas seu estado é mantido pelo Fragment Manager. Isso significa que você pode reutilizar este fragmento chamando o método attach, com um ViewHierarchy modificado

Remover significa que a instância do fragmento não pode ser anexada novamente. Você terá que adicioná-lo novamente à transação do fragmento.

Comentário da fonte

Você notará que quando um Fragment é desanexado, seus métodos onPause, onStop e onDestroyView são chamados apenas (nessa ordem). Por outro lado, quando um Fragment é removido, seus métodos onPause, onStop, onDestroyView, onDestroy e onDetach são chamados (nesta ordem). Da mesma forma, ao anexar, os métodos onCreateView, onStart e onResume do Fragment são chamados apenas; e, ao adicionar, os métodos onAttach, onCreate, onCreateView, onStart e onResume do Fragment são chamados (nessa ordem). - Adil Hussain

Rajdeep Dua
fonte
145
Para adicionar a resposta de Rajdeep, você vai notar que quando um Fragmenté destacado , seus onPause, onStope onDestroyViewmétodos são chamados apenas (nessa ordem). Por outro lado, quando um Fragmenté removido , seus onPause, onStop, onDestroyView, onDestroye onDetachmétodos são chamadas (por essa ordem). Da mesma forma, quando anexando , os Fragment's onCreateView, onStarte onResumemétodos são chamados apenas; e quando a adição , os Fragment's onAttach, onCreate, onCreateView, onStarte onResumemétodos são chamadas (por essa ordem).
Adil Hussain
1
Há uma rápida sessão de perguntas e respostas com Diane Hackborn aqui . Então, por que eu tenho esse log? Como você sabe que FT.detach () foi chamado?
Poutrathor
1
Qual é a vantagem de um sobre o outro? Quero saber um caso de uso em que um é favorável ao outro? Eu sempre adiciono e removo, isso é ruim?
Neon Warge de
1
Melhor esclarecimento curto e conciso.
Robotec
55

A nomenclatura dos métodos de gerenciamento de fragmentos é muito confusa, mesmo de acordo com os engenheiros do Google em painéis de mensagens (veja os comentários acima). Eu fiz uma pequena demonstração para descobrir como as coisas realmente funcionam. Aqui estão minhas descobertas. Sinta-se à vontade para me corrigir se eu estiver errado.

Para adicionar inicialmente um fragmento a uma atividade, você usa: getFragmentManager (). BeginTransaction (). Add (R.id.container, mFragment) .commit ().

Isso associa a Atividade ao Fragmento e também associa uma Visualização ao Fragmento.

Aqui estão os eventos de ciclo de vida resultantes e outros valores de retorno de método importantes:

onAttach()           
onCreate()           
onCreateView()       
onViewCreated()      
onActivityCreated()  
onViewStateRestored()
onStart()            
onResume()

mFragment.getView() == null: false                    
mFragment.getActivity() == null: false

Para remover um fragmento de uma atividade, você usa: getFragmentManager (). BeginTransaction (). Remove (mFragment) .commit ().

Isso remove qualquer associação com uma Visualização ou Atividade.

Aqui estão os eventos de ciclo de vida resultantes e outros valores de retorno de método importantes:

onPause()
onStop()
onDestroyView()
onDestroy()
onDetach()

mFragment.getView() == null: true
mFragment.getActivity() == null: true

Eu readicionei o fragmento aqui

Para desanexar um Fragment adicionado de uma Activity, você usa: getFragmentManager (). BeginTransaction (). Detach (mFragment) .commit ().

Isso remove qualquer associação com uma Visualização, mas mantém a associação com a Atividade.

Aqui estão os eventos de ciclo de vida resultantes e outros valores de retorno de método importantes:

onPause()                             
onStop()                              
onDestroyView()                      

mFragment.getView() == null: true
mFragment.getActivity() == null: false

Para anexar novamente um Fragment que foi desanexado à Activity, você usa: getFragmentManager (). BeginTransaction (). Attach (mFragment) .commit ().

Isso cria uma nova View para associar ao Fragment e mantém a associação Activity.

Aqui estão os eventos de ciclo de vida resultantes e outros valores de retorno de método importantes:

onCreateView()                        
onViewCreated()                       
onActivityCreated()                   
onViewStateRestored()                 
onStart()                             
onResume()                            

mFragment.getView() == null: false
mFragment.getActivity() == null: false

Outras coisas importantes a serem observadas: Se você desanexar um Fragmento e tentar adicioná-lo novamente usando add () em vez de attach (), nada parece mudar.

se você tentar adicionar um fragmento que foi removido usando remove () usando attach () ao invés de add (), nada parece mudar.

Quando getView () retorna null, o Fragment ainda pode ter referências internas para a última View que ele criou. Esta visualização não é mais válida e não deve ser usada.

Stephen
fonte
1
Bom trabalho. Mas pareceu muito interessante tentar reconectar e readicionar com o mesmo efeito após a remoção do fragmento.
stdout
9
Portanto, descobriu-se que "attach ()" não invocará onAttach (). "detach ()" não invocará onDetach ().
KunYu Tsai
1
E alguns desses eventos de ciclo de vida podem mudar ligeiramente se você mantiver as transações na pilha de retorno.
stdout