如何处理2个FragmentTransaction

时间:2019-06-04 20:24:53

标签: android android-fragments error-handling transactions

我的应用有问题,其中包含2个片段布局 当我想从抽屉项目单击同时更改两个片段的 它给我这样的错误

2019-06-04 22:22:03.572 24088-24088/com.example.android.madbaloon3 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.madbaloon3, PID: 24088
    java.lang.IllegalStateException: commit already called
        at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:669)
        at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:637)
        at com.example.android.madbaloon3.MainActivity.onNavigationItemSelected(MainActivity.java:195)
        at android.support.design.widget.NavigationView$1.onMenuItemSelected(NavigationView.java:170)
        at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:840)
        at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
        at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:991)
        at android.support.design.internal.NavigationMenuPresenter$1.onClick(NavigationMenuPresenter.java:352)
        at android.view.View.performClick(View.java:6261)
        at android.view.View$PerformClick.run(View.java:23752)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6776)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)

首先,我在课堂上设置片段内容


    private MapFragment mapFragment = new MapFragment();
    private DataFragment dataFragment = new DataFragment();
    private InfoFragment infoFragment = new InfoFragment();
    private AboutFragment aboutFragment = new AboutFragment();
    private EmptyFragment emptyFragment = new EmptyFragment();


private FragmentTransaction transaction_top = getSupportFragmentManager().beginTransaction();
private FragmentTransaction transaction_bottom = getSupportFragmentManager().beginTransaction();

然后在oncreate中,我会像这样设置默认片段

transaction_bottom.replace(R.id.bottomFragment, dataFragment);
        transaction_bottom.commit();
        bottom_fragment_name="dataFragment";


        transaction_top.replace(R.id.topFragment, mapFragment);
        transaction_top.commit();
        top_fragment_name="mapFragment";

然后我想在有人点击抽屉项目时更改两个片段

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {


        switch (item.getItemId()) {
            case R.id.nav_map:

                transaction_top.replace(R.id.topFragment, mapFragment);
                transaction_top.commit();

                break;
            case R.id.nav_about:


                transaction_top.replace(R.id.topFragment,aboutFragment);
                transaction_top.commit();


                transaction_top.replace(R.id.bottomFragment,infoFragment);
                transaction_bottom.commit();


            default:
                break;

        }

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

片段整合(我的意思是content_main.xml)

        <FrameLayout
            android:id="@+id/topFragment"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="25"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:layout="@layout/fragment_map" />

        <FrameLayout
            android:id="@+id/bottomFragment"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:layout="@layout/fragment_info"
            />

我一直在尝试删除交易中的片段,然后再替换它,但是它不起作用

2 个答案:

答案 0 :(得分:0)

您的错误状态:

  

java.lang.IllegalStateException:提交已被调用

这意味着,您正在尝试在活动中的某个位置两次提交FragmentTransaction。

您将在onNavigationItemSelected的{​​{1}}中看到您已经编写了此代码。

case R.id.nav_about

在这种情况下,您之前已经提交了transaction_bottom,但是在这里您尝试再次进行操作而不对事务进行任何更改。所以您必须将其更改为

transaction_top.replace(R.id.bottomFragment,infoFragment);
transaction_bottom.commit();

答案 1 :(得分:0)

java.lang.IllegalStateException:已调用被抛出,因为您已经提交了 transaction_top 并试图通过同一事务更改另一个片段。也许你打算写的是

 @Override
public boolean onNavigationItemSelected(MenuItem item) {

    FragmentTransaction transaction_top = getSupportFragmentManager().beginTransaction();
    FragmentTransaction transaction_bottom = getSupportFragmentManager().beginTransaction();

    switch (item.getItemId()) {
        case R.id.nav_map:

            transaction_top.replace(R.id.topFragment, mapFragment);
            transaction_top.commit();

            break;
        case R.id.nav_about:


            transaction_top.replace(R.id.topFragment,aboutFragment);
            transaction_top.commit();


            transaction_bottom.replace(R.id.bottomFragment,infoFragment);
            transaction_bottom.commit();


        default:
            break;

    }

    DrawerLayout drawer = findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

请注意,每次调用 onNavigationSelected 函数时,都必须启动新的FragmentTransactions,因为您希望更改片段。

进一步说明,您不需要创建两个单独的FragmentTransaction对象 transaction_top transaction_bottom ,您可以创建单个FragmentTransaction对象并更改其中的两个片段相同的交易如下

 @Override
public boolean onNavigationItemSelected(MenuItem item) {

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    switch (item.getItemId()) {
        case R.id.nav_map:

            transaction.replace(R.id.topFragment, mapFragment);
            transaction.commit();

            break;
        case R.id.nav_about:


            transaction.replace(R.id.topFragment,aboutFragment);
            transaction.replace(R.id.bottomFragment,infoFragment);
            transaction.commit();


        default:
            break;

    }

    DrawerLayout drawer = findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}