Уже вызвана фиксация фрагментарной транзакции Android

#android #android-fragments #fragmenttransaction

#Android #android-фрагменты #fragmenttransaction

Вопрос:

Моя ОШИБКА :

java.lang.Исключение IllegalStateException: фиксация уже вызвана

Мой КОД:

 final FragmentTransaction fragmentTransaction =getFragmentManager().beginTransaction();

f1_fragment  = new F1_Fragments();
f2_fragment = new F2_Fragments();

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            parent.getItemAtPosition(position);

            if(position==0){
                fragmentTransaction.replace(android.R.id.content, f1_fragment);
            }else{
                fragmentTransaction.replace(android.R.id.content, f2_fragment);
            }

            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();
        }
    });
  

Комментарии:

1. вы уже совершили фиксацию по этой транзакции, вам нужно запустить новую транзакцию, если вы хотите снова совершить фиксацию fragmentTransaction = getFragmentManager().beginTransaction();

Ответ №1:

Вы начинаете выполнение FragmentTransaction за пределами OnItemClickListener . Таким образом, вы пытаетесь commit() выполнить одну FragmentTransaction каждый раз, когда пользователь нажимает на элемент в вашем ListView.

Вам нужно начинать новую FragmentTransaction каждый раз, когда вы собираетесь выполнить любое количество операций с фрагментами.

Простое исправление будет выглядеть следующим образом:

 f1_fragment  = new F1_Fragments();
f2_fragment = new F2_Fragments();

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        FragmentTransaction fragmentTransaction =getFragmentManager().beginTransaction();

        parent.getItemAtPosition(position);

        if(position==0){
            fragmentTransaction.replace(android.R.id.content, f1_fragment);
        }else{
            fragmentTransaction.replace(android.R.id.content, f2_fragment);
        }

        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();
    }
});
  

Комментарии:

1. Спасибо!!!! есть ли лучший способ сделать это? я реализую Listview в SlidingMenu.

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

3. у меня это работает. Я действительно ценю вашу помощь. Спасибо.

Ответ №2:

вы можете использовать этот метод для замены фрагментов друг на друга, просто вызовите это

являются ли они глобальными

 YourFragment1 frg1 = new   YourFragment1 ();    
YourFragment2 frg1 = new   YourFragment2 (); 
  

А затем вызовите его с помощью

 openFragment(frg1); 
  

или

   openFragment(frg2);
  

OpenFragment:

   private void openFragment(final Fragment fragment)   {
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();        
    transaction.replace(R.id.container, fragment);
    transaction.addToBackStack(null);
    transaction.commit();

}
  

Комментарии:

1. спасибо, а также создание fragmentManager частного поля — идея получше 🙂

Ответ №3:

Посмотрите на этот сценарий

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

 switch (v.getId()) {

                case R.id.tvaddExpense:

                    fragmentTransaction = getFragmentManager().beginTransaction();
                    fragmentTransaction.add(R.id.containerFucntionsList, new Fragment1());
                    fragmentTransaction.addToBackStack(null);
                    fragmentTransaction.commit();
                    break;

                case R.id.relEvents:
                    fragmentTransaction = getFragmentManager().beginTransaction();
                    fragmentTransaction.replace(R.id.containerFucntionsList, new Fragment2());
                    fragmentTransaction.addToBackStack(null);
                    fragmentTransaction.commit();
                    break;
            } 
  

Ответ №4:

У меня была такая же проблема, и я решил ее, создав новый экземпляр FragmentTransaction .

Просто добавляйте каждый раз строку ниже перед добавлением / заменой фрагмента.

 FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
  

Надеюсь, это поможет вам.

Ответ №5:

Ошибка

java.lang.Исключение IllegalStateException: фиксация уже вызвана

показывает, что FragmentTransaction был завершен после вызова commit() в первый раз, и вы снова вызываете, commit() что приводит к повторному завершению. Следовательно, это создает недопустимое состояние для FragmentTransaction .

Согласно вашему коду, вы используете то же самое FragmentTransaction для изменения фрагментов. Однако после первого commit() вызова операция FragmentTransaction завершена, и вам нужно начать ее снова, чтобы выполнить какую-либо операцию над Fragments .

Вы можете изменить свой ClickListner как:

 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override

    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            fragmentTransaction = getSupportFragmentManager().beginTransaction();   

            parent.getItemAtPosition(position);

            if(position==0){
                fragmentTransaction.replace(android.R.id.content, f1_fragment);
            }else{
                fragmentTransaction.replace(android.R.id.content, f2_fragment);
            }

            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();
        }
    });
  

Я надеюсь, что это устраняет ваши сомнения.

Ответ №6:

Вы должны определять объект FragmentTransaction отдельно каждый раз, когда добавляете фрагмент:

      switch (position){
                case 0:
                    FragmentTransaction fragmentTransaction1 = getSupportFragmentManager().beginTransaction();
                    fragmentTransaction1.replace(R.id.parentOfMenu, new FragmentHome());
                    fragmentTransaction1.commit();

                    break;
                case 1:
                    FragmentTransaction fragmentTransaction2 = getSupportFragmentManager().beginTransaction();
                    fragmentTransaction2.replace(R.id.parentOfMenu, new FragmentMedia());
                    fragmentTransaction2.commit();

                    break;

                case 2:
                    FragmentTransaction fragmentTransaction3 = getSupportFragmentManager().beginTransaction();
                    fragmentTransaction3.replace(R.id.parentOfMenu, new FragmentChart());
                    fragmentTransaction3.commit();

                    break;

                case 3:
                    FragmentTransaction fragmentTransaction4 = getSupportFragmentManager().beginTransaction();
                    fragmentTransaction4.replace(R.id.parentOfMenu, new FragmentProfile());
                    fragmentTransaction4.commit();

                    break;
            }
  

Ответ №7:

Я решил проблему после вызова commit() и снова заменил фрагмент, с которого вы должны начать

 fragmentTransaction = fragmentManager.beginTransaction();

if(position==0){
     fragmentTransaction.replace(android.R.id.content, f1_fragment);
 else{
     fragmentTransaction.replace(android.R.id.content, f2_fragment);
 }

 fragmentTransaction.addToBackStack(null);
 fragmentTransaction.commit();