Estou usando a biblioteca de compatibilidade do Android para implementar fragmentos e estendemos o exemplo de layout para que um fragmento contenha um botão que dispara outro fragmento.
No painel de seleção à esquerda, tenho 5 itens selecionáveis - A B C D E
.
Cada um carrega um fragmento (via FragmentTransaction:replace
) no painel de detalhes -a b c d e
Agora estendi o fragmento e
para conter um botão que carrega outro fragmento e1
também no painel de detalhes. Eu fiz isso no e
método onClick do fragmento da seguinte maneira:
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.details_frag, newFrag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
Se eu fizer as seguintes seleções:
E - e - e1 - D - E
Em seguida, o fragmento e
está no painel de detalhes. Isso está bem e o que eu quero. No entanto, se eu apertar o back
botão neste momento, não faz nada. Eu tenho que clicar duas vezes, porque e1
ainda está na pilha. Além disso, depois de clicar ao redor, recebi uma exceção de ponteiro nulo no onCreateView:
Para 'resolver' esse problema, adicionei o seguinte sempre que A B C D E
é selecionado:
FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
Imaginando se essa é a solução correta ou se eu deveria estar fazendo algo diferente.
A outra solução limpa, se você não quiser exibir todas as entradas da pilha ...
Isso limpará a pilha primeiro e, em seguida, carregará um novo fragmento; portanto, a qualquer momento, você terá apenas um fragmento na pilha
fonte
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
antes de um replace (), porque estão carregando o chamado FragmentoonCreateView()
,onActivityCreated()
etc. Restaurar e Destroing um Fragmento instantaneamente é ruim. O fragmento pode registrar um receptor, por exemplo. Isso afeta o desempenho.FragmentTransaction
? Existe apenas um desempenho ruim da pilha de fragmentos incorreta?Graças à resposta do Joachim , uso o código para limpar todas as entradas da pilha traseira finalmente.
fonte
popBackStack(backStackId, INCLUSIVE)
exibirá todos os fragmentos (estados) de volta ao backStackId; assim, quando você exibir o menor númeroi
que você irá exibir, todos os itens mais altos deverão aparecer ao mesmo tempo. Então, qual é o sentido de um loop?Pesquisei bastante para limpar o Backstack e, finalmente, consulte o Transaction BackStack e seu gerenciamento . Aqui está a solução que funcionou melhor para mim.
O método acima faz um loop em todas as transações no backstack e as remove imediatamente uma de cada vez.
Nota: o código acima, em algum momento, não funciona e eu enfrento o ANR por causa desse código, portanto, não tente isso.
A atualização abaixo do método remove todos os fragmentos desse "nome" do backstack.
fonte
Estou usando um código semelhante aos que usam o loop while, mas eu chamo a contagem de entradas em cada loop ... então suponho que seja um pouco mais lento
fonte
Conforme escrito em Como destacar fragmento do backstack e por LarsH aqui, podemos vários fragmentos de cima para baixo para uma tag específica ( junto com o fragmento marcado ) usando este método:
Substitua "frag" pela tag do seu fragmento. Lembre-se de que primeiro devemos adicionar o fragmento ao backstack com:
Se adicionarmos fragmentos
addToBackStack(null)
, não apareceremos os fragmentos dessa maneira.fonte
fonte