Fragment onResume() & onPause() nie jest wywoływany na backstack

Mam wiele fragmentów wewnątrz aktywności. Po kliknięciu przycisku uruchamiam nowy fragment, dodając go do backstacka. Naturalnie oczekiwałem wywołania metody onPause() bieżącego fragmentu i onResume() nowego fragmentu. To się nie dzieje.

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();
  }
}

Czego się spodziewałem, było,

  1. Po kliknięciu przycisku, LoginFragment zostanie zastąpiony przez HomeFragment, onPause() z LoginFragment i onResume() z HomeFragment zostaje wywołany
  2. po naciśnięciu back, HomeFragment jest poped out i LoginFragment jest seen, and onPause() of HomeFragment and onResume() of LoginFragment ktoś dzwoni.

To co dostaję to,

  1. Po kliknięciu przycisku, HomeFragment {[20] } poprawnie zastępuje loginfragment, onresume() z homefragment jest wywoływany, ale onPause() z LoginFragment nigdy nie jest wywoływany.
  2. po naciśnięciu do tyłu, HomeFragment jest poprawnie wyskakujący, aby odsłonić LoginFragment , onPause() z HomeFragment zostanie wywołany, ale onResume() z LoginFragment nigdy nie zostanie wywołany.
Czy to normalne zachowanie? Dlaczego onResume()z LoginFragment Nie jest wywoływany po naciśnięciu przycisku Wstecz.
Author: galvan, 2012-07-04

15 answers

Fragmenty onResume() LUB onPause() będą wywoływane tylko wtedy, gdy zostaną wywołane działania onResume() LUB onPause(). Są one ściśle powiązane z Activity.

Przeczytaj Obsługa sekcji cyklu życia fragmentu tego artykułu .

 154
Author: Sagar Waghmare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-22 10:06:17
  • ponieważ użyłeś ft2.replace(), FragmentTransaction.remove() metoda zostanie wywołana i Loginfragment zostanie usunięta. Zobacz to . Tak więc onStop() z LoginFragment będą wywoływane zamiast onPause(). (Jako nowy fragment całkowicie zastępuje stary).
  • Ale skoro masz również używany ft2.addtobackstack(), Stan {[2] } będzie zapisany jako pakiet i po kliknięciu przycisku wstecz z HomeFragment, onViewStateRestored() będzie wywoływana po onStart() z LoginFragment. Więc ostatecznie onResume() nie zostanie wywołany.
 18
Author: Gopal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-27 14:10:38

Jeśli naprawdę chcesz zastąpić fragment wewnątrz innego fragmentu, powinieneś użyć zagnieżdżonych fragmentów .

W kodzie należy zastąpić

final FragmentManager mFragmentmanager =  getFragmentManager();

Z

final FragmentManager mFragmentmanager =  getChildFragmentManager();
 8
Author: Bersh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-11 23:46:32

Oto moja bardziej solidna Wersja odpowiedzi Gora (z wykorzystaniem fragmentów.size()jest zawodne ze względu na to, że rozmiar nie jest zmniejszany po wystąpieniu fragmentu)

getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            if (getFragmentManager() != null) {

                Fragment topFrag = NavigationHelper.getCurrentTopFragment(getFragmentManager());

                if (topFrag != null) {
                    if (topFrag instanceof YourFragment) {
                        //This fragment is being shown. 
                    } else {
                        //Navigating away from this fragment. 
                    }
                }
            }
        }
    });

I metoda "getCurrentTopFragment":

public static Fragment getCurrentTopFragment(FragmentManager fm) {
    int stackCount = fm.getBackStackEntryCount();

    if (stackCount > 0) {
        FragmentManager.BackStackEntry backEntry = fm.getBackStackEntryAt(stackCount-1);
        return  fm.findFragmentByTag(backEntry.getName());
    } else {
        List<Fragment> fragments = fm.getFragments();
        if (fragments != null && fragments.size()>0) {
            for (Fragment f: fragments) {
                if (f != null && !f.isHidden()) {
                    return f;
                }
            }
        }
    }
    return null;
}
 5
Author: aaronmarino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-24 17:41:30

Mam kod bardzo podobny do twojego i jeśli działa onPause () i onResume (). Podczas zmiany fragmentu funkcje te są aktywowane odpowiednio.

Kod we fragmencie:

 @Override
public void onResume() {
    super.onResume();
    sensorManager.registerListener(this, proximidad, SensorManager.SENSOR_DELAY_NORMAL);
    sensorManager.registerListener(this, brillo, SensorManager.SENSOR_DELAY_NORMAL);
    Log.e("Frontales","resume");
}

@Override
public void onPause() {
    super.onPause();
    sensorManager.unregisterListener(this);
    Log.e("Frontales","Pause");

}

Log przy zmianie fragmentu:

05-19 22:28:54.284 2371-2371/madi.cajaherramientas E/Frontales: resume
05-19 22:28:57.002 2371-2371/madi.cajaherramientas E/Frontales: Pause
05-19 22:28:58.697 2371-2371/madi.cajaherramientas E/Frontales: resume
05-19 22:29:00.840 2371-2371/madi.cajaherramientas E/Frontales: Pause
05-19 22:29:02.248 2371-2371/madi.cajaherramientas E/Frontales: resume
05-19 22:29:03.718 2371-2371/madi.cajaherramientas E/Frontales: Pause

Fragment onCreateView:

View rootView;
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    rootView = inflater.inflate(R.layout.activity_proximidad, container, false);
    ButterKnife.bind(this,rootView);
    inflar();
    setTextos();
    return rootView;
}

Akcja, gdy pulsuję z powrotem (w aktywności, w której Ładuję fragment):

@Override
public void onBackPressed() {

    int count = getFragmentManager().getBackStackEntryCount();

    if (count == 0) {
        super.onBackPressed();

    } else {
        getFragmentManager().popBackStack();
    }

 }
 2
Author: PepitoGrillo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-19 20:45:14

You simple can ' t add a fragment to a fragment. To musi się zdarzyć w fragmencie. Zakładam, że tworzysz LoginFragment w FragmentActivity, więc aby to działało, musisz dodać HomeFragment za pomocą FragmentActivity, gdy login się zamyka.

Ogólnie rzecz biorąc, potrzebujesz klasy FragmentActivity, z której dodajesz każdy Fragment do Menedżera Fragmentmanagera. nie jest możliwe aby to zrobić wewnątrz klasy Fragment.

 1
Author: Nickolaus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-11 16:38:46

Jeśli dodasz fragment w XML, nie możesz zamienić go dynamicznie. To, co się dzieje, jest przesadnie, więc nie strzelają tak, jak można by się spodziewać. Problem jest udokumentowany w tym pytaniu. FragmenManager replace sprawia, że nakładka

Zamień middle_fragment w FrameLayout i załaduj go jak poniżej, a twoje zdarzenia zostaną uruchomione.

getFragmentManager().beginTransation().
    add(R.id.middle_fragment, new MiddleFragment()).commit();
 1
Author: Dustin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:26
getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            List<Fragment> fragments = getFragmentManager().getFragments();
            if (fragments.size() > 0 && fragments.get(fragments.size() - 1) instanceof YoureFragment){
                //todo if fragment visible
            } else {
                //todo if fragment invisible
            }

        }
    });

Ale uważaj, jeśli widoczny jest więcej niż jeden fragment

 1
Author: Gor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-13 13:47:59

What I do in child fragment:

@Override
public void onDetach() {
   super.onDetach();
   ParentFragment pf = (ParentFragment) this.getParentFragment();
   pf.onResume();
}

A następnie nadpisać onResume na ParentFragment

 1
Author: Guillermo De Juan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-10 09:01:58

Fragment musi być zawsze osadzony w aktywności, a cykl życia fragmentu jest bezpośrednio zależny od cyklu życia aktywności hosta. Na przykład, gdy aktywność jest wstrzymana, tak są w niej wszystkie fragmenty, a gdy aktywność jest zniszczona, tak są wszystkie fragmenty

 0
Author: Xar E Ahmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-16 11:29:20

Możesz spróbować tego,

Krok 1: nadpisanie metody Tabselected w aktywności

@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    // When the given tab is selected, switch to the corresponding page in
    // the ViewPager.
    try {
    if(MyEventsFragment!=null && tab.getPosition()==3)
    {
        MyEvents.fragmentChanged();
    }
    }
    catch (Exception e)
    {

    }
    mViewPager.setCurrentItem(tab.getPosition());
}

Krok 2: używając metody statycznej zrób to, co chcesz w swoim fragmencie,

public static void fragmentChanged()
{
    Toast.makeText(actvity, "Fragment Changed", Toast.LENGTH_SHORT).show();
}
 0
Author: Manoj Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-20 12:25:31

onPause() metoda działa w klasie activity, której możesz użyć:

public void onDestroyView(){
super.onDestroyView    
}

W tym samym celu..

 0
Author: Vikrant Kaloniya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-02 19:29:51

Wykonaj poniższe kroki, a otrzymasz potrzebną odpowiedź

1-dla obu fragmentów utwórz nowy abstrakcyjny rodzic.
2-Dodaj niestandardową metodę abstrakcyjną, która powinna być zaimplementowana przez oba z nich.
3-wywołaj ją z bieżącej instancji przed zastąpieniem drugą.

 0
Author: Mostafa Magdy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-09 21:09:33

Na podstawie odpowiedzi @ Gor napisałem podobne w Kotlinie. Umieść ten kod w onCreate() aktywności. Działa na jeden widoczny fragment. Jeśli masz {[2] } z fragmentami, wywoła on fragment ViewPager, a nie poprzedni.

supportFragmentManager.addOnBackStackChangedListener {
    supportFragmentManager.fragments.lastOrNull()?.onResume()
}

Po przeczytaniu https://medium.com/@elye.project/puzzle-fragment-stack-pop-cause-issue-on-toolbar-8b947c5c07c6 zrozumiałem, że w wielu sytuacjach lepiej będzie dołączyć nowe fragmenty replace, a nie add. Więc potrzeba w onResume w niektóre przypadki znikną.

 0
Author: CoolMind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-02 12:39:38

Podczas tworzenia transakcji fragment, należy dodać następujący kod.

// Replace whatever is in the fragment_container view with this fragment, 
// and add the transaction to the back stack 
transaction.replace(R.id.fragment_container, newFragment); 
transaction.addToBackStack(null); 

Upewnij się również, aby zatwierdzić transakcję po dodaniu jej do backstack

 -2
Author: Mayur More,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-07 13:26:44