Atividade:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment1 fragment = new Fragment1();
Fragment2 fragment2 = new Fragment2();
transaction.replace(R.id.Fragment1, fragment);
transaction.addToBackStack(null);
transaction.commit();
FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction();
transaction2.replace(R.id.Fragment1, fragment2);
transaction2.addToBackStack(null);
transaction2.commit();
Código na visualização:
<fragment
android:id="@+id/Fragment1"
android:name="com.landa.fragment.Fragment1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="@+id/include1" />
O problema é que o conteúdo não é realmente substituído - ele é colocado por cima (de modo que se sobrepõe).
Quando clico de volta, o primeiro fragmento é mostrado corretamente (sem o segundo), mas inicialmente ambos estão visíveis (quero que apenas o último esteja visível).
O que estou perdendo aqui?
android
android-fragments
Ferramenta
fonte
fonte
containerViewId
(noreplace
método).Respostas:
Você está fazendo duas coisas erradas aqui:
Você não pode substituir um fragmento que é colocado estaticamente em um
xml
arquivo de layout. Você deve criar um contêiner (por exemplo, aFrameLayout
) no layout e, em seguida, adicionar o fragmento de forma programática usandoFragmentTransaction
.FragmentTransaction.replace
espera o id do contêiner que contém o fragmento e não o id do fragmento como o primeiro parâmetro. Portanto, você deve passar o primeiro argumento como o id do contêiner ao qual adicionou o primeiro fragmento.Você pode consultar este link para mais detalhes.
fonte
FrameLayout
como recipiente é melhor do que usarLinearLayout
.addTobackStack(..)
ao fazer sua transação pela primeira vez. Isso evitará colocar o contêiner FrameLayout vazio na pilha traseira. Você ainda poderá navegar de volta ao fragmento que adicionou.Eu tive um problema semelhante, mas meu problema era que eu estava usando dois gerenciadores de fragmentos diferentes: um de
getSupportFragmentManager()
e um degetFragmentManager()
. Se eu adicionasse um fragmento com oSupportFragmentManager
e, em seguida, tentasse substituir o fragmento com oFragmentManager
, o fragmento seria apenas adicionado por cima. Eu precisava mudar o código para que o mesmoFragmentManager
fosse usado e isso resolveu o problema.fonte
O site do desenvolvedor Android sugere o uso de um
FrameLayout
para carregar fragmentos dinamicamente em tempo de execução. Você codificou o fragmento em seu arquivo xml. Portanto, ele não pode ser removido em tempo de execução, conforme mencionado neste link:http://developer.android.com/training/basics/fragments/creating.html
este link mostra como adicionar fragmentos por meio de seu programa:
http://developer.android.com/training/basics/fragments/fragment-ui.html
fonte
Tive o mesmo problema e vi todas as respostas, mas nenhuma delas continha o meu erro! Antes de tentar substituir o fragmento atual, eu estava mostrando o fragmento padrão no xml da atividade do contêiner assim:
depois disso, embora eu estivesse passando o
FrameLayout
para o,fragmentTransaction.replace()
mas eu tive o problema exato. estava mostrando o segundo fragmento em cima do anterior.O problema foi corrigido removendo o fragmento do xml e mostrando-o programaticamente no
onCreate()
método da atividade do contêiner para a visualização padrão no início do programa assim:e o xml de atividade do contêiner:
fonte
Você pode limpar backStack antes de substituir fragmentos:
fonte
Adicione
android:background="?android:windowBackground">
ao recipiente em que reside o seu fragmento. No meu caso, adicionei umFrameLayout
, isso deve ajudar.fonte
Use um contêiner em vez de fragmento
Agora em MainActivity
Observe que sua classe de fragmento deve importar 'android.app.Fragment'. Certifique-se de usar "support.v4" ou as implementações "originais" e não as misture. Eu estava tendo esse problema porque os mixei.
fonte
Eu concordo com a resposta de Sapan Diwakar. Mas eu encontrei uma solução alternativa para fazer isso.
Primeiro, em sua atividade (por exemplo
activity_main
), onde você tem todos os layouts, adicione aFrameLayout
. Sua altura e largura devem sermatch parent
. Além disso, dê umid
.Agora, em seu fragmento que vai substituir o layout atual, chame
onPause()
eonResume()
. Inicialize todos os recipientes internos emView
. E defina seusvisibility
paraGONE
dentroonResume()
e paraVISIBLE
dentroonPause()
.NOTA : Não o
FrameLayout
que você está substituindo com este fragmento.Suponha que você tenha
ViewPager
,TabLayout
,ImageView
e um costume<fragment>
noactivity_main.xml
. Adicione, aFrameLayout
conforme mencionado acima.Em
abcFragment.java
, emonClick()
função, adicioneaddToBackstack(null)
emtransaction
.Código de exemplo:
em xyzFragment, que vai substituir abcFragment (e tudo mostrado em activity_main.xml), faça isso
Boa codificação!
fonte
Você pode usar o método setTransition de FragmentTransaction para corrigir o problema de sobreposição.
fonte
Em Oncreate ()
agora, este será sempre o seu fragmento padrão ... se você adicionar o fragmento no layout xml, ele sempre se sobreporá, então defina o conteúdo inicial com o fragmento em tempo de execução
fonte
eu tive o mesmo problema depois de usar este problema resolvido
Pegue o layout do quadro onde você está substituindo seu fragmento
e código para substituição
Se você quiser um exemplo completo, vou enviar-lhe apenas um comentário ...
fonte
Eu também tive o mesmo problema, mas foi porque eu não alterei a cor de fundo do fragmento que estava tentando adicionar ao meu layout de moldura.
Tente fazer isso, com
layout_height
elayout_width
definido paramatch_parent
fonte
Uma vez eu tive esse problema e descobri que era porque eu havia excluído acidentalmente o
android:background
atributo que está faltando no seu código xml. Acredito que funcione como quando você está pintando uma parede,android:background
é a cor que a parede vai ficar e as outras vistas são colocadas em cima dessa cor base. Quando você não pinta a parede antes de posicionar suas vistas, elas estarão em cima do que já estava naquela parede, no seu caso, seu outro fragmento. Não sei se isso vai te ajudar, boa sorte.fonte
Tentei acima de tudo o caso e tentei consertar o problema, mas ainda não consegui solução. Eu não sei por que não está funcionando para mim. Eu concordo com as respostas acima porque muitos concordam com isso.
Estou apenas estendendo a resposta e abaixo está o caminho que está funcionando para mim.
Espero que alguém consiga ajuda.
fonte
Obrigado a Sapan Diwakar e outros. Essa resposta me ajudou. Eu simplesmente criei um RelativeLayout sem um fragmento dentro dele, usei o RelativeLayout como uma visão pai ou de grupo, especifiquei essa visão de grupo na transação a ser substituída e funcionou.
Código:
XML:
fonte
Verifique seu ID de layout de quadro e substitua-o como abaixo
fonte