2016-12-29 2 views
1

Я разрабатываю приложение с фрагментами из библиотеки поддержки. Я использую только одно действие. Макет состоит из макета координатора с макетом панели сворачивания и представления навигации. При выборе элемента навигации я выполнить следующее в NavigationItemSelectedListener:onResume призвал к «мертвым» фрагментам - как правильно восстановить?

switch (item.getItemId()) { 
       default: 
        return false; 
       case R.id.mainmenu_start: 
        navi.clear(); 
        navi.navigate(new StartFragment(), R.id.fragment_container); 
        return true; 
       // ... More menu entries 
      } 

Так, при выборе нового пункта я очистить backstack (navi.clear()) и замените отображаемый фрагмент с новым.

Проблема у меня есть: «старые» (замененные) фрагменты не удаляются/удаляются.

Так что, когда я перейти к StartFragment, а затем перейти к другому фрагменту, а затем снова выбрать StartFragment, то onResume вызывается дважды:
После того, как на «старый»/первый StartFragment после того, как на вновь созданный один.

Как я могу избежать такого поведения? Я или хочу использовать существующие фрагменты (первый) или создать новый - но с использованием как приводит к массовым проблемам ...

Чтобы исследовать это поведение я дал каждый фрагмент уникальный (инкрементный) ID: Когда переходя к новому фрагменту, onResume вызывается на нескольких старых фрагментах, но не на всех из них.
Например: я всегда выбираю одно и то же меню для навигации. Это такие "события" происходящий, где число указывает Fragment ID (все фрагменты того же класса (StartFragment)):

  1. Создание 1, резюме 1
  2. Создание 2, Резюме 1, Резюме 2
  3. Создание 3, Резюме 1, Резюме 3
  4. Создание 4, Резюме 2, 3 Резюме, Резюме 4

Так что иногда "старые" фрагменты отсутствуют и вернуться позже. onResume иногда также называют совершенно разными фрагментами. (Так что, когда я открыл фрагмент-ранее, onResume на Фрагмент 2 также называется при создании нового фрагмента 1 ...)

Для полноты
Навигационной функции:

public void clear() { 
    FragmentManager fragmentManager = ((MainActivity)context).getSupportFragmentManager(); 
    fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 
} 



public void navigate(Fragment fragment, int container, HashMap<String, Pair<String, View>> sharedElements) { 
    this.hideKeyboard(); 
    FragmentTransaction ft = ((MainActivity)context).getSupportFragmentManager().beginTransaction(); 
    ft.replace(container, fragment); 
    ft.addToBackStack(null); 
    ft.commit(); 
    ((MainActivity)context).getDrawerLayout().closeDrawers(); 
} 
+1

Первая мысль: Пытались ли вы popBackStackImmediate вместо popBackStack? Любая разница? –

+1

Спасибо! Это похоже на правильное решение! Возможно, вы хотите опубликовать это как ответ, поэтому я могу принять его – Kryptur

+0

Конечно, я отправлю его как отдельный ответ –

ответ

1

отправляет как ответ для дальнейшего использования.

Я думаю, что ваша проблема в том, что popBackStack() не имеет немедленного эффекта, но планируется запустить следующий проход цикла событий, который в вашем случае слишком поздний и дает нежелательные эффекты. Что должно помочь, так это принудительное завершение транзакции диспетчера фрагментов.

Это может быть достигнуто либо путем вызова executePendingTransactions() или в данном конкретном случае popBackStackImmediate()