как бороться с 2 FragmentTransaction - PullRequest
0 голосов
/ 04 июня 2019

У меня проблема с моим приложением, которое содержит 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();

, затем при создании я устанавливаю фрагмент по умолчанию, подобный этому

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

фрагмент loyout (я имею в виду 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 голосов
/ 05 июня 2019

java.lang.IllegalStateException: коммит, уже вызванный , генерируется, потому что вы зафиксировали action_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;
}

Обратите внимание, что вы должны запускать новые FragmentTransactions каждый раз, когда вызывается функция onNavigationSelected , потому что вы хотите изменить фрагменты.

Кроме того, вам не нужно создавать два отдельных объекта FragmentTransaction action_top и action_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;
}
0 голосов
/ 04 июня 2019

Ваша ошибка гласит:

java.lang.IllegalStateException: коммит уже вызван

Это означает, что вы пытаетесь дважды зафиксировать FragmentTransaction где-то в вашей активности.

Вы сможете увидеть, в вашем onNavigationItemSelected, в case R.id.nav_about, вы написали этот код.

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

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

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