How do I fix Fragment already added in my code?

I open a dialog fragment from A fragment, and when the dialog fragment is closed, I want to switch from A fragment to B fragment at the same time.

But I keep getting Fragment already added error.

I am using show() instead of replace() to change the screen.

Fragment already added error was easily solved on the web, but I don’t work out weird.

Probably there is a problem with my code, please let me know where the problem is.

MainActivity.java

public class MainActivity extends AppCompatActivity {
    BottomNavigationView bottomNav;
    FragmentManager fm;
    FragmentTransaction transaction;
    Fragment curFrag;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bottomNav = findViewById(R.id.bottom_nav);

        bottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                fm = getSupportFragmentManager();
                transaction = fm.beginTransaction();
                curFrag = fm.getPrimaryNavigationFragment();
                String tag = String.valueOf(item.getItemId());
                int id = item.getItemId();

                if(curFrag != null) {
                    transaction.hide(curFrag);
                }

                Fragment fragment = fm.findFragmentByTag(tag);
                if(fragment == null) {
                    if(id == R.id.list)
                        fragment = new WorkoutListFragment();
                    transaction.add(R.id.content_layout, fragment, tag);
                }
                else {
                    transaction.show(fragment);
                }

                transaction.setPrimaryNavigationFragment(fragment);
                transaction.setReorderingAllowed(true);
                transaction.commitNow();
                return true;
            }
        });
    }

    // Method for screen switching
    public void onFragmentChanged() {
//        transaction = fm.beginTransaction();
        String tag = "WriteRoutine";

        curFrag = fm.getPrimaryNavigationFragment();
        if (curFrag != null) {
            transaction.hide(curFrag);
        }

        Fragment fragment = fm.findFragmentByTag(tag);

        if (fragment == null) {
            fragment = new WriteRoutineFragment();
            fragment.setArguments(curFrag.getArguments());
            transaction.add(R.id.content_layout, fragment, tag);
        } else {
            transaction.show(fragment);
        }

        transaction.setReorderingAllowed(true);
        transaction.commit();
    }
}

WorkoutListFragment.java (A Fragment)

public class WorkoutListFragment extends Fragment {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);

        getParentFragmentManager().setFragmentResultListener("result", this, new FragmentResultListener(){
            @Override
            public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle result) {
                if(result != null)
                    WorkoutListFragment.this.setArguments(result);
                    titleData = result.getStringArrayList("title");
            }
        });
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.activity_workout_list, container, false);
        initViews(rootView);
        ((AppCompatActivity) getActivity()).setSupportActionBar((toolbar));

        return rootView;
    }

    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        menu.clear();
        inflater = getActivity().getMenuInflater();
        inflater.inflate(R.menu.record_item_add, menu);
    }

    @Override // open dialog
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        BodyPartDialogFragment dialog = new BodyPartDialogFragment();
        dialog.show(getActivity().getSupportFragmentManager(), "BodyPartDialog");
        return true;
    }
}

DialogFragment.java

public class BodyPartDialogFragment extends DialogFragment {

    Button startBtn;
    ArrayList<String> bodypart_strData;
    int selectedNum;

    final static String TAG = "DialogFragment";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_body_part_dialog, null);
        startBtn = view.findViewById(R.id.check);
        
        // A D D
        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(selectedNum == 0){
                    Toast.makeText(getContext(), "Plaese select", Toast.LENGTH_SHORT).show();
                }
                else {
                    MainActivity activity = (MainActivity) getActivity();
                    Bundle result = new Bundle();
                    result.putStringArrayList("title", bodypart_strData);
                    getParentFragmentManager().setFragmentResult("result", result);
                    activity.onFragmentChanged();
                    dismiss();
                }
            }
        });

        return view;
}

Answer

Upon testing your code, you’ll just need to reinstantiate the transaction object before adding/replacing your fragment.

So, you need to add below in onFragmentChanged():

transaction = getSupportFragmentManager().beginTransaction();

And here it is:

// Method for screen switching
public void onFragmentChanged() {

    String tag = "WriteRoutine";

    transaction = getSupportFragmentManager().beginTransaction(); // <<< THE CHANGE IS HERE
    curFrag = fm.getPrimaryNavigationFragment();
    if (curFrag != null) {
        transaction.hide(curFrag);
    }

    Fragment fragment = fm.findFragmentByTag(tag);

    if (fragment == null) {
        fragment = new WriteRoutineFragment();
        fragment.setArguments(curFrag.getArguments());
        transaction.add(R.id.content_layout, fragment, tag);
    } else {
        transaction.show(fragment);
    }

    transaction.setReorderingAllowed(true);
    transaction.commit();
}