Intereting Posts
Как сделать ход для 3 сторон для формы в андроиде? Слишком много шаблонов, как я могу уменьшить свои строители POJO? Как сохранить состояние Android CheckBox, когда пользователи выходят из приложения? Несколько игроков Youtube в одном действии Как разрешать только положительные числа в EditText Опубликовать вариант приложения для Android в отключенном состоянии в Xamarin с помощью Visual studio 2015 ViewPager – получить частичный вид следующей страницы Android SDK менеджер не загружает все уровни API Приложение Android извлекает данные с сервера, но безопасным способом Как использовать adb grant или adb revoke? Точки останова не работают во время отладки собственной библиотеки Android в Visual Studio 2015 Как показать элементы действия внизу с помощью панели инструментов Определение CameraUpdate с помощью LatLngBounds с различными значениями заполнения Какое разрешение экрана я должен учитывать при разработке приложения для Android? Сомнение в создании пользовательского представления с помощью Android

Фрагменты все еще добавляются в backstack без вызова addToBackStack, почему?

Я создаю вспомогательный класс для замены фрагмента, и у меня есть некоторые проблемы с ним.

Я называю это FragmentChanger

У этого есть fragmentContainer , который является ViewGroup , который содержит все фрагменты, которые я хотел бы показать.

Я сделал свою собственную replace(Fragment fragmentToChange, boolean needSaveToBackStack)

Функция, которая:

  • Удаление старого фрагмента фрагментаContainer
  • Добавление нового фрагмента к фрагментуContainer
  • При необходимости сохраняет значение backStack, а needSaveToBackStacktrue или false .

Ошибка заключается в следующем:

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

Но когда я хотел бы заменить фрагмент без сохранения на backStack, в моем коде есть что-то не так, потому что, когда я отступаю, я вижу на экране фрагмент, который я НЕ добавил в backStack , и ТАКЖЕ, я могу видеть другое Ранее был добавлен фрагмент в одно и то же время!

Таким образом, я могу видеть 2 фрагмента в одно и то же время, например:

Введите описание изображения здесь

Это мой код:

 //It is my helper class to handle replacing fragments. public class FragmentChanger { // fragmentTransaction FragmentTransaction fragmentTransaction; // the container for fragments ViewGroup fragmentContainer; // activity ofc Activity act; // Ctr: adding a default fragment to be the first so we can see it at app // start public FragmentChanger(Activity act, ViewGroup container, Fragment startingFragment) { this.act = act; this.fragmentContainer = container; fragmentTransaction = act.getFragmentManager().beginTransaction(); fragmentTransaction.add(container.getId(), startingFragment, startingFragment.getClass().getSimpleName()); fragmentTransaction.addToBackStack(startingFragment.getClass().getSimpleName()); fragmentTransaction.commit(); } // Replacing a fragment with an other one public void replace(Fragment fragmentToChange, boolean needSaveToBackStack) { fragmentTransaction = act.getFragmentManager().beginTransaction(); // replacing old fragment to the new one! fragmentTransaction.replace(fragmentContainer.getId(), fragmentToChange, fragmentToChange.getClass().getSimpleName()); // Some null checking, and if the new fragment is NOT equals the current // fragment if (getCurrentFragment() != null && getCurrentFragment() != fragmentToChange) { /*** Important** because something here is wrong ***/ // only addToBackStack when i want it, when needSaveToBackStack = // true! if (needSaveToBackStack) { fragmentTransaction.addToBackStack(fragmentToChange.getClass().getSimpleName()); } } // commiting changes fragmentTransaction.commit(); } // getting current Fragment private Fragment getCurrentFragment() { try { FragmentManager fragmentManager = act.getFragmentManager(); String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName(); Fragment currentFragment = act.getFragmentManager().findFragmentByTag(fragmentTag); return currentFragment; } catch (Exception ex) { ex.printStackTrace(); } return null; } // Logging the back stack public void logBackStack() { Log("Logging back stack:", "============="); FragmentManager fragmentManager = act.getFragmentManager(); int stackSize = fragmentManager.getBackStackEntryCount(); Log("Fragments count on the stack: ", stackSize + ""); for (int i = 0; i < stackSize; i++) { String fragmentTag = fragmentManager.getBackStackEntryAt(i).getName(); Log("Fragment on the stack: ", fragmentTag); } } private void Log(String str, String msg) { Log.i(str, msg); } } 

И это моя MainActivity, где я проверяю класс вспомогательного фрагмента:

 public class MainActivity extends Activity implements OnClickListener { // My 3 Fragment Classes, could be N other type, // in this example I only got 3 FragmentA fragmentA; FragmentB fragmentB; FragmentC fragmentC; // Button to add the fragments manually Button addA, addB, addC; // This is my activity's container, its a simple viewGroup // could be anything that can hold fragments ViewGroup fragmentContainer; // This is my fragment changer helper class that need some revision by you // guys FragmentChanger fragmentChanger; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //defining my adding buttons addA = (Button)findViewById(R.id.addAbtn); addB = (Button)findViewById(R.id.addBbtn); addC = (Button)findViewById(R.id.addCbtn); //setting onclicklistenrs addA.setOnClickListener(this); addB.setOnClickListener(this); addC.setOnClickListener(this); // defining my main container, this will holds fragments fragmentContainer = (ViewGroup) findViewById(R.id.fragmentContainer); // defining my fragments, each of them got an Activity (this), a // Container (mainContainer), and a Layout ofc. fragmentA = new FragmentA(this, fragmentContainer, R.layout.fragment_a_layout); fragmentB = new FragmentB(this, fragmentContainer, R.layout.fragment_b_layout); fragmentC = new FragmentC(this, fragmentContainer, R.layout.fragment_c_layout); // defining my fragment changer with an activity(this), a // container(mainContent) and a starting fragment to show! fragmentChanger = new FragmentChanger(this, fragmentContainer, fragmentA); } @Override public void onClick(View view) { if (view.equals(addA)) { //When adding fragmentA, i always want to save it to backstack fragmentChanger.replace(fragmentA, true); } else if (view.equals(addB)) { //I dont want to save to back stack when adding B //So if i press back button, i dont want to see fragmentB ever again. //(But i do see, this is the error.) fragmentChanger.replace(fragmentB, false); } else if (view.equals(addC)) { //When adding fragmentC, i always want to save it to backstack fragmentChanger.replace(fragmentC, true); } //After any modification on fragments, i log the backstack fragmentChanger.logBackStack(); } 

}

Ps: Я могу ясно видеть, что фрагментB никогда не находится на backStack, если я регистрирую стек каждый раз, когда я заменяю фрагмент моим вспомогательным классом. Тогда почему это появляется, если я нажимаю кнопку?

Я очень признателен за любые советы, это моя первая попытка использования фрагментов с моим собственным вспомогательным классом, и я хотел бы сделать его очень полезным.

Solutions Collecting From Web of "Фрагменты все еще добавляются в backstack без вызова addToBackStack, почему?"

Итак, вот что я нашел не так с вашим кодом:

1) Вы смешиваете теги Fragment и BackStackEntry .

 String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName(); 

Итак, здесь вы получаете тег BackStackEntry (не Fragment ), который вы добавляете или нет в fragmentTransaction.addToBackStack() . Следовательно, вы получаете неправильное состояние и используете его как текущий фрагмент.

2) Как правило, не рекомендуется хранить и повторно использовать фрагменты, как в ваших классах: FragmentA fragmentA; , Это может привести к проблемам с состоянием и инфляцией, лучше создавать их при каждой транзакции, если вы не хотите решать дополнительные головоломки.

Попробуйте заменить фрагмент с помощью метода FragmentTransacion.replace, как показано в ссылке здесь.

И вы также можете ссылаться на этот пример. Это отлично работает для меня.

Во-первых, в конструкторе класса FragmentChanger вы добавляете все фрагменты в свою заднюю часть. Поскольку вы добавляете их в порядок, они добавляются как A, B, а затем C. После добавления их в стопку в этом порядке вы делаете больше транзакций поверх него. Инициализируя их, не добавляйте их в заднюю часть. Добавляйте / удаляйте их только при нажатии кнопки.

В вашем коде есть много заметок, поэтому я не знаю, как это исправить, но я могу дать общий обзор того, что вы должны делать.

Если вы хотите добавить фрагмент в backStack, тогда сделайте .replace(params ).addToBackStack(Tag)

Если вы не хотите добавлять определенный фрагмент, просто полностью пропустите addToBackStack(Tag) .

Также ваш getCurrentFragment() можно изменить на

Fragment currentFrag=getFragmentManager().findFragmentById(R.id.fragment_container);

Прочтите этот ОТВЕТ здесь для лучшего объяснения, а также этот ОТВЕТ