When I used fragment (.add) method and used “fade_in/fade_out” animation When moving between them. It is gives me this error “java.lang.IllegalStateException: commit already called”. I followed this tutorial to add fragments and this question to use animation.
Her’s my code
final Fragment fragment1 = new HomeFragment(); final Fragment fragment2 = new LibraryFragment(); final Fragment fragment3 = new ImageFragment(); final FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); Fragment active = fragment1; private void initializeBottomNavigation() { // animations ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out); ft.setCustomAnimations(android.R.anim.fade_out, android.R.anim.fade_in); // add fragments ft.add(R.id.fragment_layout, fragment3, "3").hide(fragment3).commit(); ft.add(R.id.fragment_layout, fragment2, "2").hide(fragment2).commit(); ft.add(R.id.fragment_layout,fragment1, "1").commit(); // show and hid them when click on BottomNav items BottomNavigationView navigationView = findViewById(R.id.bottom_navigation); navigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.home_item: ft.hide(active).show(fragment1).commit(); active = fragment1; return true; case R.id.books_item: ft.hide(active).show(fragment2).commit(); active = fragment2; return true; case R.id.image_item: ft.hide(active).show(fragment3).commit(); active = fragment3; return true; } return false; } }); }
Advertisement
Answer
FragmentTransaction
is a one-time use object. You shouldn’t reuse it in multiple actions, but rather start a new transaction every time you want to change some Fragments.
In your case this is: once during initialisation, and once on every bottom bar press.
First of all, remove the line FragmentTransition ft = fm.beginTransaction()
from the top since you can’t reuse that object.
Then change the function like so where you create a new transaction for every button press:
private void initializeBottomNavigation() { // first one transaction to add each Fragment FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.fragment_layout, fragment3, "3").hide(fragment3); ft.add(R.id.fragment_layout, fragment2, "2").hide(fragment2); ft.add(R.id.fragment_layout, fragment1, "1"); // commit once! to finish the transaction ft.commit(); // show and hide them when click on BottomNav items BottomNavigationView navigationView = findViewById(R.id.bottom_navigation); navigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { // start a new transaction FragmentTransaction ft = fm.beginTransaction(); // animations ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out); ft.setCustomAnimations(android.R.anim.fade_out, android.R.anim.fade_in); switch (item.getItemId()) { case R.id.home_item: ft.hide(active).show(fragment1).commit(); active = fragment1; return true; case R.id.books_item: ft.hide(active).show(fragment2).commit(); active = fragment2; return true; case R.id.image_item: ft.hide(active).show(fragment3).commit(); active = fragment3; return true; } return false; } }); }