【问题标题】:Android FragmentTransaction commit already calledAndroid FragmentTransaction 提交已调用
【发布时间】:2014-08-25 01:26:05
【问题描述】:

我的错误:

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();
        }
    });

【问题讨论】:

  • 您已经对该事务进行了提交,如果您想再次提交,则需要开始一个新事务fragmentTransaction = getFragmentManager().beginTransaction();

标签: android android-fragments fragmenttransaction


【解决方案1】:

您在 OnItemClickListener 之外开始 FragmentTransaction。因此,每次用户单击 ListView 中的项目时,您都试图 commit() 一个 FragmentTransaction。

每次您打算执行任意数量的 Fragment 操作时,都需要开始一个新的 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();
    }
});

【讨论】:

  • 谢谢!!!!有没有最好的方法来做到这一点?我在 SlidingMenu 中实现 Listview。
  • 据我所知,您使用的模式看起来不错。
  • 它对我有用。我真的很感谢你的帮助。谢谢。
【解决方案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();

}

【讨论】:

  • 谢谢,同时将 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】:

    错误

    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();
            }
        });
    

    我希望它能消除你的疑问。

    【讨论】:

      【解决方案5】:

      我遇到了同样的问题,我通过创建FragmentTransaction新实例解决了。

      只需在 add / replace 片段之前的行下方添加 everytime

      FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
      

      希望这会对你有所帮助。

      【讨论】:

        【解决方案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();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-06-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多