Gostaria de saber se isso é realmente um bug na API do Android:
Eu tenho uma configuração assim:
┌----┬---------┐
| | |
| 1 | 2 |
| |┌-------┐|
| || ||
| || 3 ||
└----┴┴-------┴┘
- É um menu que carrega o fragmento # 2 (uma tela de pesquisa) no painel direito.
- É uma tela de pesquisa que contém o fragmento 3, que é uma lista de resultados.
- A lista de resultados é usada em vários lugares (inclusive como um fragmento de alto nível em funcionamento).
Essa funcionalidade funciona perfeitamente bem em um telefone (onde 1 e 2 e 3 são ActivityFragment
).
No entanto, quando eu usei este código:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment frag = new FragmentNumber2();
if(toLoad != null) frag.setArguments(toLoad);
transaction.replace(R.id.rightPane, frag);
transaction.commit();
Onde R.id.leftPane
e R.id.rightPane
estão <fragment>
s em um layout linear horizontal.
Entendo que o código acima remove o fragmento que é residente e o substitui por um novo fragmento. Brilhante ... Obviamente, não é isso que acontece, porque quando esse código é executado pela segunda vez, você obtém a seguinte exceção:
07-27 15:22:55.940: ERROR/AndroidRuntime(8105): Caused by: java.lang.IllegalArgumentException: Binary XML file line #57: Duplicate id 0x7f080024, tag null, or parent id 0x0 with another fragment for FragmentNumber3
Isso é causado porque o contêiner de FragmentNumber3 foi duplicado e não possui mais um ID exclusivo. O fragmento inicial não foi destruído (?) Antes da adição do novo (na minha opinião, isso significa que não foi substituído ).
Alguém pode me dizer se isso é possível ( esta resposta sugere que não é) ou é um bug?
Respostas:
Fragmentos aninhados não são suportados no momento. Tentar colocar um fragmento na interface do usuário de outro fragmento resultará em comportamento indefinido e provavelmente interrompido.
OBSERVAÇÃO (conforme este documento ): " Observação: você não pode aumentar um layout em um fragmento quando esse layout inclui a
<fragment>
. Fragmentos aninhados são suportados apenas quando adicionados dinamicamente a um fragmento. "fonte
Fragment
Agora, os aninhados fazem parte da API do Android! developer.android.com/about/versions/… .A Biblioteca de suporte do Android também agora suporta fragmentos aninhados , para que você possa implementar designs de fragmentos aninhados no Android 1.6 e superior.
Para aninhar um fragmento, basta chamar getChildFragmentManager () no fragmento no qual você deseja adicionar um fragmento. Isso retorna um FragmentManager que você pode usar como normalmente faz na atividade de nível superior para criar transações de fragmento. Por exemplo, aqui está um código que adiciona um fragmento de dentro de uma classe Fragment existente:
Para ter uma idéia mais detalhada sobre fragmentos aninhados, consulte estes tutoriais
Parte 1
Parte 2
Parte 3
e aqui está uma postagem do SO que discute sobre as práticas recomendadas para fragmentos aninhados .
fonte
.. você pode limpar seu fragmento aninhado no
destroyview
método do fragmento pai :fonte
Eu tenho um aplicativo que estou desenvolvendo que é semelhante a Tabs na barra de ação que lança fragmentos, alguns desses fragmentos possuem vários fragmentos incorporados.
Eu estava recebendo o mesmo erro quando tentei executar o aplicativo. Parece que se você instanciar os fragmentos no layout xml após a seleção de uma guia e depois a selecionar novamente, eu receberia o erro do inflador.
Resolvi isso substituindo todos os fragmentos em xml por Linearlayouts e, em seguida, usando uma transação de fragmento / gerenciador de fragmentos para instanciar os fragmentos, tudo parece funcionar corretamente pelo menos em um nível de teste no momento.
Espero que isso ajude você.
fonte
Eu enfrentei o mesmo problema, lutei alguns dias com ele e devo dizer que a maneira mais fácil de superar isso foi encontrar fragment.hide () / fragment.show () quando a guia é selecionada / desmarcada ()
Quando ocorre a rotação da tela, todos os fragmentos pai e filho são destruídos corretamente.
Essa abordagem também tem uma vantagem adicional - o uso de hide () / show () não faz com que as exibições de fragmentos percam seu estado; portanto, não há necessidade de restaurar a posição de rolagem anterior para ScrollViews, por exemplo.
O problema é que não sei se é correto não desanexar fragmentos quando eles não estão visíveis. Eu acho que o exemplo oficial do TabListener é projetado com um pensamento em mente de que os fragmentos são reutilizáveis e você não deve poluir com a memória deles. será apropriado mantê-los ligados à atividade atual.
Eu gostaria de ouvir comentários de desenvolvedores mais experientes.
fonte
Se você encontrar o seu fragmento aninhado não sendo removido ou duplicado (por exemplo, na reinicialização da atividade, na rotação da tela), tente alterar:
para
Se acima não ajudar, tente:
Aprendido aqui
fonte