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,
- Po kliknięciu przycisku, LoginFragment zostanie zastąpiony przez
HomeFragment,
onPause()
z LoginFragment ionResume()
z HomeFragment zostaje wywołany - po naciśnięciu back, HomeFragment jest poped out i LoginFragment jest
seen, and
onPause()
of HomeFragment andonResume()
of LoginFragment ktoś dzwoni.
To co dostaję to,
- 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.
- 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.
onResume()
z LoginFragment Nie jest wywoływany po naciśnięciu przycisku Wstecz. 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 .
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 iLoginfragment
zostanie usunięta. Zobacz to . Tak więconStop()
zLoginFragment
będą wywoływane zamiastonPause()
. (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 zHomeFragment
,onViewStateRestored()
będzie wywoływana poonStart()
zLoginFragment
. Więc ostatecznieonResume()
nie zostanie wywołany.
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();
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;
}
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();
}
}
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.
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();
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
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
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
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();
}
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..
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ą.
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ą.
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
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