5

У меня есть Activity с тремя Fragments позволяет называть их , B и C. FragmentA вызывается в Управлении onCreate().Предотвращение и тот же фрагмент из штабелирования более одного раза (addToBackStack)

FragmentA fragA = new FragmentA(); 
FragmentTransaction transaction = manager.beginTransaction(); 
transaction.add(R.id.activity2_layout, fragA, "A"); 
transaction.commit(); 

И заменяется Fragment B или C когда определенные кнопки нажимаются, и FragmentTransaction называет addToBackStack().

FragmentB fragB = new FragmentB(); //or C 
FragmentTransaction transaction = manager.beginTransaction(); 
transaction.replace(R.id.activity2_layout, fragB, "B"); //or C 
transaction.addToBackStack("B"); //or C 
transaction.commit(); 

Но позволяет сказать, что я называю FragmentB три раза подряд, как я могу предотвратить его укладки на нее самостоятельно? И в то же время я хочу, чтобы это было возможно: B называется>C называется>B называется - НО когда я пытаюсь вернуться, я хочу B быть открыт только один раз (C < B) вместо (B < C < в). Таким образом, в основном удаление первого backStack с новым.

ответ

8

От How to resume Fragment from BackStack if exists, что может быть очень похоже на ваш запрос.

Существует способ поместить задний стек на основе либо имени транзакции, либо идентификатора, предоставленного фиксацией (например,используя имя фрагмента класса, как Тайс уже упоминалось):

String backStateName = fragment.getClass().getName(); 

Добавление к backstack:

FragmentTransaction ft = manager.beginTransaction(); 
ft.replace(R.id.content_frame, fragment); 
ft.addToBackStack(backStateName); 
ft.commit(); 

Когда появляются:

getSupportFragmentManager().popBackStackImmediate (backStateName, 0); 

Так что перед заменой фрагмента, мы можем проверить существования в backstack like:

boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0); 

if (!fragmentPopped){ //fragment not in back stack, create it. 
    ... 
    ... 
    ft.addToBackStack(backStateName); 
    ft.commit(); 
} 

Пожалуйста, проверьте приведенный выше вопрос и принятый ответ для получения более подробного объяснения.

+0

Это лучший ответ, поскольку он отвечает на оба вопроса :) –

1

Я решил один из ваших вопросов, а именно how can I prevent it from stacking on to it self?, в одном из моих собственных проектов. Это был точный код, который я использовал там:

public void setContent(@NonNull Fragment fragment, boolean addToBackStack) { 
    Fragment current = getSupportFragmentManager().findFragmentById(R.id.main_content); 
    if (current == null || !current.getClass().equals(fragment.getClass())) { 
     FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
     if (addToBackStack) { 
      transaction.addToBackStack(null).add(R.id.main_content, fragment).commit(); 
     } else { 
      transaction.replace(R.id.main_content, fragment).commit(); 
     } 
    } 
} 

Что делает этот код проверки того, что класс в настоящее время показывает фрагмент, и сравнить с фрагментом вы хотите, чтобы заменить его. Если они одинаковы, это ничего не делает. Этот код может быть сформирован в соответствии с вашими потребностями, как так

Fragment newFragment = new FragmentB(); //OR FragmentC 
Fragment current = getSupportFragmentManager().findFragmentById(R.id.activity2_layout); 
if (!current.getClass().equals(newFragment.getClass())) { 

    //POP BACKSTACK HERE LIKE EXPLAINED BELOW 

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
    final String tag = newFragment.getClass().getSimpleName(); 
    transaction.addToBackStack(tag); 
    transaction.add(R.id.activity2_layout, newFragment, tag); 
    transaction.commit(); 
} else { 
    //THROW AN ERROR OR SOMETHING, HANDLE IT BEING THE SAME 
} 

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

+0

Спасибо. Ни один пример не понадобится :) Единственное, что мне нужно выяснить сейчас, это как удалить backStacks, которые уже были сделаны, даже если это возможно, так как я не могу найти никакой документации или примеров на что. –

+1

Я не думаю, что это возможно вообще. Насколько мне известно, «FragmentManager» имеет один и только один сток. Вы можете поместить записи, а затем добавить еще один, чтобы «заменить» это количество записей одной новой записью. Пока вы делаете это до того, как вы совершаете 'commit()', вы должны быть в порядке :) –

+0

@IvanJavorovic, удалив backStacks, вы имеете в виду очистить задний стек? –