Eu tenho vários fragmentos dentro de uma atividade. Em um botão, estou iniciando um novo fragmento, adicionando-o ao backstack. Eu naturalmente esperava que o onPause()
método do fragmento atual e onResume()
do novo fragmento fosse chamado. Bem, isso não está acontecendo.
LoginFragment.java
public class LoginFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.login_fragment, container, false);
final FragmentManager mFragmentmanager = getFragmentManager();
Button btnHome = (Button)view.findViewById(R.id.home_btn);
btnHome.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
HomeFragment fragment = new HomeFragment();
FragmentTransaction ft2 = mFragmentmanager.beginTransaction();
ft2.setCustomAnimations(R.anim.slide_right, R.anim.slide_out_left
, R.anim.slide_left, R.anim.slide_out_right);
ft2.replace(R.id.middle_fragment, fragment);
ft2.addToBackStack("");
ft2.commit();
}
});
}
@Override
public void onResume() {
Log.e("DEBUG", "onResume of LoginFragment");
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of loginFragment");
super.onPause();
}
}
HomeFragment.java
public class HomeFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.login_fragment, container, false);
}
@Override
public void onResume() {
Log.e("DEBUG", "onResume of HomeFragment");
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of HomeFragment");
super.onPause();
}
}
O que eu esperava era
- Quando o botão é clicado, o LoginFragment é substituído por
HomeFragment ,
onPause()
de LoginFragment eonResume()
de HomeFragment chamado - Quando volta é pressionado, HomeFragment é poped fora e LoginFragment é visto, e
onPause()
de HomeFragment eonResume()
de LoginFragment é chamado.
O que estou recebendo é,
- Quando o botão é clicado, o HomeFragment está substituindo corretamente o LoginFragment , onResume () do HomeFragment é chamado, mas a onPause () do LoginFragment nunca é chamada.
- Quando pressionado novamente, o HomeFragment aparece corretamente para revelar o LoginFragment , a onPause () do HomeFragment é chamada, mas o onResume () do LoginFragment nunca é chamado.
Esse é o comportamento normal? Por que é onResume()
de LoginFragment não ser chamado quando pressiono o botão de volta.
android
android-fragments
onresume
back-stack
Krishnabhadra
fonte
fonte
Respostas:
Os fragmentos
onResume()
ouonPause()
serão chamados apenas quando as AtividadesonResume()
ouonPause()
forem chamados. Eles estão fortemente acoplados aoActivity
.Leia a seção Manipulando o ciclo de vida do fragmento deste artigo .
fonte
onPause()
ser chamado depois eonSaveInstanceState()
não antes. Isso pode ser reproduzida se a uma criança diferente na minhaFragmentStatePagerAdapter
(dizer que você passar de criança 0 a criança 2, nota para si mesmo, isso acontece porque criança 0 é destruída quando criança 2 abre )ft2.replace()
, oFragmentTransaction.remove()
método é chamado e oLoginfragment
será removido. Consulte isso . Então,onStop()
deLoginFragment
será chamado em vez deonPause()
. (Como o novo fragmento substitui completamente o antigo).ft2.addtobackstack()
, o estado doLoginfragment
será salvo como um pacote e, quando você clicar no botão Voltar deHomeFragment
,onViewStateRestored()
será chamado seguido poronStart()
deLoginFragment
. Então, eventualmenteonResume()
, não será chamado.fonte
onViewStateRestored
é chamado se você tiversetRetainInstance(true)
Aqui está a minha versão mais robusta da resposta de Gor (o uso de fragments.size () não é confiável devido ao tamanho não ser diminuído após o fragmento ser populado)
E o método 'getCurrentTopFragment':
fonte
Se você realmente deseja substituir fragmentos dentro de outro fragmento, use Fragmentos Aninhados .
No seu código, você deve substituir
com
fonte
mas tenha cuidado se mais de um fragmento visível
fonte
ViewPager
fragmentos farão referência aos seus fragmentos).Eu tenho um código muito semelhante ao seu e se ele funciona em onPause () e onResume (). Ao alterar o fragmento, essas funções são ativadas respectivamente.
Código no fragmento:
Registre quando a alteração do fragmento:
Fragmento onCreateView:
Ação quando pulso de volta (na atividade em que carrego o fragmento):
fonte
O que eu faço no fragmento filho:
E, em seguida, substitua onResume em ParentFragment
fonte
Você simplesmente não pode adicionar um fragmento a um fragmento. Isso precisa acontecer no FragmentActivity. Suponho que você esteja criando o LoginFragment em um FragmentActivity, portanto, para que isso funcione, é necessário adicionar o HomeFragment por meio do FragmentActivity quando o login for fechado.
O ponto geral é que você precisa de uma classe FragmentActivity de onde você adiciona cada fragmento ao FragmentManager. Não é possível fazer isso dentro de uma classe Fragment.
fonte
Se você adicionar o fragmento em XML, não poderá trocá-los dinamicamente. O que acontece é que eles são excessivamente, para que os eventos não disparem como seria de esperar. O problema está documentado nesta pergunta. Substituição FragmenManager faz sobreposição
Transforme middle_fragment em um FrameLayout e carregue-o como abaixo e seus eventos serão acionados.
fonte
Você pode tentar isso,
Etapa 1: substituir o método Tabselected em sua atividade
Etapa 2: usando o método estático, faça o que você deseja no seu fragmento,
fonte
Eu uso na minha atividade - KOTLIN
fonte
Um fragmento sempre deve ser incorporado a uma atividade e o ciclo de vida do fragmento é diretamente afetado pelo ciclo de vida da atividade do host. Por exemplo, quando a atividade está em pausa, todos os fragmentos estão nela e, quando a atividade é destruída, todos os fragmentos também.
fonte
onPause()
O método funciona na classe de atividade que você pode usar:para a mesma finalidade ..
fonte
Siga as etapas abaixo e obterá a resposta necessária
1- Para ambos os fragmentos, crie um novo pai abstrato.
2- Adicione um método abstrato personalizado que deve ser implementado por ambos.
3- Chame a partir da instância atual antes de substituir pela segunda.
fonte
Com base na resposta de @Gor , escrevi semelhante em Kotlin. Coloque esse código em
onCreate()
uma atividade. Funciona para um fragmento visível. Se você tiverViewPager
fragmentos, ele chamaráViewPager
o fragmento, não o anterior.Depois de ler https://medium.com/@elye.project/puzzle-fragment-stack-pop-cause-issue-on-toolbar-8b947c5c07c6 , entendi que seria melhor em muitas situações anexar novos fragmentos
replace
, nãoadd
. Portanto,onResume
em alguns casos, a necessidade desaparecerá.fonte
Chamando
ft.replace
deve acionar onPause (do fragmento substituído) e onResume (do fragmento de substituição).Percebo que seu código é inflado
login_fragment
no fragmento de origem e também não retorna as visualizações no onCreateView. Se estes são erros de digitação, você pode mostrar como esses fragmentos estão sendo chamados de dentro da sua atividade?fonte
Embora com código diferente, tive o mesmo problema do OP, porque originalmente usei
ao invés de
Com "substituir", o primeiro fragmento é recriado quando você retorna do segundo fragmento e, portanto, onResume () também é chamado.
fonte
Ao criar uma transação de fragmento, adicione o seguinte código.
Certifique-se também de confirmar a transação após adicioná-la ao backstack
fonte