Android - Не удалось зафиксировать транзакцию - PullRequest
0 голосов
/ 11 марта 2020

Здравствуйте, я новичок в сцене Android,

У меня проблема с изменением фрагмента с использованием FragmentTransaction, что не так с кодом? Насколько я знаю, проблема заключается в коммите, потому что его вызывают дважды, но не похоже, что это возможно, и я не вижу такого поведения в отладчике.

package com.example.foodgent.Logic;

import android.annotation.SuppressLint;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.ViewPager;

import com.example.foodgent.UserInterface.Fragment2;
import com.example.foodgent.UserInterface.Fragment3;
import com.example.foodgent.UserInterface.MainActivity;
import com.example.fragment.R;

public class FragmentChanger<mainActivity>  extends AppCompatActivity {

    private Button btnNavFrag1;
    private Button btnNavFrag2;
    private Button btnNavFrag3;
    private MainActivity mainActivity;
    private int currentPage;
    public FragmentChanger(Button btnNavFrag1, Button btnNavFrag2, Button btnNavFrag3, MainActivity activity) {
        this.btnNavFrag1 = btnNavFrag1;
        this.btnNavFrag2 = btnNavFrag2;
        this.btnNavFrag3 = btnNavFrag3;
        this.mainActivity= mainActivity;
        currentPage=0;
    }



    @SuppressLint("RestrictedApi")
    public void change(int number, ViewPager viewPager){

   final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    switch (number) {
            case 0:
                if (currentPage != 0) {
                    btnNavFrag1.setBackgroundResource(R.drawable.fragment_active_button);
                    btnNavFrag2.setBackgroundResource(R.drawable.fragment_buttons);
                    btnNavFrag3.setBackgroundResource(R.drawable.fragment_buttons);

                    // Replace whatever is in the fragment_container view with this fragment,
                    // and add the transaction to the back stack if needed
                    transaction.replace(R.id.fragment, new Fragment());

                    transaction.addToBackStack(null);
                    transaction.commit();
                }
                break;

            case 1:
                if (currentPage != 1) {
                    btnNavFrag1.setBackgroundResource(R.drawable.fragment_buttons);
                    btnNavFrag2.setBackgroundResource(R.drawable.fragment_active_button);
                    btnNavFrag3.setBackgroundResource(R.drawable.fragment_buttons);

                    // Replace whatever is in the fragment_container view with this fragment,
                    // and add the transaction to the back stack if needed
                    transaction.replace(R.id.fragment, new Fragment2());

                    transaction.addToBackStack(null);
                    transaction.commit();
                }
                break;
            case 2:

                if (currentPage != 2) {
                    btnNavFrag1.setBackgroundResource(R.drawable.fragment_buttons);
                    btnNavFrag2.setBackgroundResource(R.drawable.fragment_buttons);
                    btnNavFrag3.setBackgroundResource(R.drawable.fragment_active_button);


                    // Replace whatever is in the fragment_container view with this fragment,
                    // and add the transaction to the back stack if needed
                    transaction.replace(R.id.fragment, new Fragment3());

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

                break;

        }

        currentPage=number;
        //set the new Page
        viewPager.setCurrentItem(number);
    }

    public int getCurrentPage(){
        return currentPage;
    }
}

Ошибка:

AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.fragment, PID: 24603
    java.lang.IllegalStateException: Activity has been destroyed
        at androidx.fragment.app.FragmentManagerImpl.enqueueAction(FragmentManagerImpl.java:1566)
        at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:317)
        at androidx.fragment.app.BackStackRecord.commit(BackStackRecord.java:282)
        at com.example.foodgent.Logic.FragmentChanger.change(FragmentChanger.java:82)
        at com.example.foodgent.UserInterface.MainActivity.setViewPager(MainActivity.java:111)
        at com.example.foodgent.UserInterface.MainActivity$6.onClick(MainActivity.java:366)
        at android.view.View.performClick(View.java:6669)
        at android.view.View.performClickInternal(View.java:6638)
        at android.view.View.access$3100(View.java:789)
        at android.view.View$PerformClick.run(View.java:26145)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6898)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
W/OPDiagnose: getService:OPDiagnoseService NULL
D/OSTracker: OS Event: crash
I/Process: Sending signal. PID: 24603 SIG: 9
Process 24603 terminated.

Класс фрагмента:

package com.example.foodgent.UserInterface;


import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.example.fragment.R;


public class Fragment1 extends Fragment {

    private static final String TAG = "Fragment1";

    private Button btnNavFrag1;
    private Button btnNavFrag2;
    private Button btnNavFrag3;
    private Button btnNavSecondActivity;
    Activity mainActivity;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment1_layout, container, false);


            return view;

    }
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        if (activity != null) {
            try {
                mainActivity = activity;
            }
            catch (ClassCastException e) {
                Log.v(TAG, "Exception: " + e.getLocalizedMessage());
            }
        }
    }
}

Ответы [ 3 ]

1 голос
/ 11 марта 2020

Имеете ли вы ссылку на активность в этих фрагментах? попробуйте сохранить / обновить действие в фрагменте onAttach:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    if (activity != null) {
        try {
            mainActivity = activity;
        }
        catch (ClassCastException e) {
            Log.v(TAG, "Exception: " + e.getLocalizedMessage());
        }
    }
}

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

Сохранение ссылки на новое действие в onAttach обновит эту ссылку.

0 голосов
/ 12 марта 2020

Я удалил класс Fragment Changer и изменил фрагмент внутри Mainactivity

Проблема была в транзакции.commit (), из-за того, что я не могу вызвать ее более одного раза в FragmentChanger, ошибка произошло после нажатия кнопки Tab.

0 голосов
/ 11 марта 2020

Если ошибка происходит во время транзакции .mit ()? затем вы можете заключить звонок внутрь, проверив, не заканчивается ли действие.

if (!this.isFinishing()){
        transaction.commit();
}
...