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