У меня есть несколько фрагментов внутри деятельности. По нажатию кнопки я начинаю новый фрагмент, добавляя его в backstack. Я естественно ожидал, что будет вызван onPause()
метод текущего фрагмента и onResume()
нового фрагмента. Ну, это не происходит.
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();
}
}
То, что я ожидал, было,
- Когда кнопка нажата, LoginFragment заменяется
HomeFragment ,
onPause()
из LoginFragment , иonResume()
из HomeFragment вызывается - Когда снова нажата, HomeFragment будет poped, и LoginFragment видно, и
onPause()
из HomeFragment иonResume()
из LoginFragment вызывается.
Что я получаю,
- Когда кнопка нажата, HomeFragment корректно заменяет LoginFragment , вызывается onResume () HomeFragment , но onPause () LoginFragment никогда не вызывается.
- При обратном нажатии HomeFragment корректно появляется, чтобы показать LoginFragment , вызывается onPause () HomeFragment , но onResume () LoginFragment никогда не вызывается .
Это нормальное поведение? Почему onResume()
из LoginFragment не вызывался , когда я нажимаю кнопку назад.
android
android-fragments
onresume
back-stack
Krishnabhadra
источник
источник
Ответы:
Фрагменты
onResume()
илиonPause()
будут называться только тогда, когда деятельностьonResume()
илиonPause()
называется. Они тесно связаны сActivity
.Прочитайте раздел «Обработка жизненного цикла фрагмента» этой статьи .
источник
onPause()
вызова после,onSaveInstanceState()
а не перед этим. Это может быть воспроизведено, если вы принадлежите другому моему ребенкуFragmentStatePagerAdapter
(например, вы переходите от ребенка 0 к ребенку 2, обратите внимание на себя, это происходит потому, что ребенок 0 уничтожается, когда открывается ребенок 2 )ft2.replace()
,FragmentTransaction.remove()
метод вызывается иLoginfragment
будет удален. Обратитесь к этому . ТакonStop()
изLoginFragment
будет называться вместоonPause()
. (Так как новый фрагмент полностью заменяет старый).ft2.addtobackstack()
, состояниеLoginfragment
будет сохранено в виде пакета, и когда вы нажмете кнопку назад изHomeFragment
,onViewStateRestored()
будет вызван, а затемonStart()
оLoginFragment
. Так что в конечном итогеonResume()
не будет называться.источник
onViewStateRestored
называется, если у вас естьsetRetainInstance(true)
Вот моя более надежная версия ответа Гора (использование fragments.size () ненадежно из-за того, что размер не уменьшается после извлечения фрагмента)
И метод getCurrentTopFragment:
источник
Если вы действительно хотите заменить фрагмент внутри другого фрагмента, используйте вложенные фрагменты. .
В вашем коде вы должны заменить
с участием
источник
но будьте осторожны, если видно более одного фрагмента
источник
ViewPager
с фрагментами будет ссылаться на его фрагменты).У меня есть код, очень похожий на ваш, и если он работает onPause () и onResume (). При изменении фрагмента эти функции активируются соответственно.
Код в фрагменте:
Лог при смене фрагмента:
Фрагмент onCreateView:
Действие при возврате импульса (в упражнении, в котором я загружаю фрагмент):
источник
Что я делаю в дочернем фрагменте:
И затем переопределить onResume на ParentFragment
источник
Вы просто не можете добавить фрагмент к фрагменту. Это должно произойти в FragmentActivity. Я предполагаю, что вы создаете LoginFragment в FragmentActivity, поэтому для того, чтобы это работало, вам нужно добавить HomeFragment через FragmentActivity при закрытии входа в систему.
В общем, вам нужен класс FragmentActivity, из которого вы добавляете каждый фрагмент в FragmentManager. Это невозможно сделать внутри класса Fragment.
источник
Если вы добавите фрагмент в XML, вы не сможете поменять их динамически. То, что происходит, они чрезмерно, так что события не происходят, как можно было бы ожидать. Проблема задокументирована в этом вопросе.FragmenManager заменяет делает оверлей
Превратите middle_fragment в FrameLayout и загрузите его, как показано ниже, и ваши события сработают.
источник
Вы можете попробовать это,
Шаг 1: переопределите метод Tabselected в вашей деятельности
Шаг 2: Используя статический метод, делайте что хотите в своем фрагменте,
источник
На основании ответа @Gor я написал подобное в Kotlin. Поместите этот код в
onCreate()
деятельности. Это работает для одного видимого фрагмента. Если у вас естьViewPager
фрагменты, он будет называтьViewPager
фрагмент, а не предыдущий.Прочитав https://medium.com/@elye.project/puzzle-fragment-stack-pop-cause-issue-on-toolbar-8b947c5c07c6, я понял, что во многих ситуациях было бы лучше присоединять новые фрагменты
replace
, а неadd
. Так что необходимость вonResume
некоторых случаях исчезнет.источник
Я использую в своей деятельности - KOTLIN
источник
Фрагмент всегда должен быть встроен в действие, и жизненный цикл фрагмента напрямую зависит от жизненного цикла хоста. Например, когда действие приостановлено, то все фрагменты в нем, а когда действие уничтожено, то все фрагменты
источник
onPause()
Метод работает в классе деятельности вы можете использовать:для той же цели ..
источник
Выполните следующие шаги, и вы получите нужный ответ
1- Для обоих фрагментов создайте новый абстрактный родительский.
2. Добавьте собственный абстрактный метод, который должен быть реализован обоими.
3- Вызовите его из текущего экземпляра перед заменой на второй.
источник
призвание
ft.replace
должен вызывать onPause (замещенного фрагмента) и onResume (замещающего фрагмента).Я замечаю, что ваш код надувается
login_fragment
на домашний фрагмент, а также не возвращает представления в onCreateView. Если это опечатки, можете ли вы показать, как эти фрагменты вызываются из вашей деятельности?источник
Хотя с другим кодом я столкнулся с той же проблемой, что и OP, потому что изначально использовал
вместо того
При «замене» первый фрагмент воссоздается, когда вы возвращаетесь из второго фрагмента, и поэтому также вызывается onResume ().
источник
При создании транзакции фрагмента обязательно добавьте следующий код.
Также убедитесь, что зафиксировали транзакцию после добавления ее в backstack.
источник