Following is my code for bottom navigation view item selected
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationI
With support library v26 you can do this
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
Fragment curFrag = mFragmentManager.getPrimaryNavigationFragment();
if (curFrag != null) {
fragmentTransaction.detach(curFrag);
}
Fragment fragment = mFragmentManager.findFragmentByTag(tag);
if (fragment == null) {
fragment = new YourFragment();
fragmentTransaction.add(container.getId(), fragment, tag);
} else {
fragmentTransaction.attach(fragment);
}
fragmentTransaction.setPrimaryNavigationFragment(fragment);
fragmentTransaction.setReorderingAllowed(true);
fragmentTransaction.commitNowAllowingStateLoss();
This seemed to work well for me. Instead of attaching and detaching, i use show or hide to maintain fragment state.
public void changeFragment(Fragment fragment, String tagFragmentName) {
FragmentManager mFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
Fragment currentFragment = mFragmentManager.getPrimaryNavigationFragment();
if (currentFragment != null) {
fragmentTransaction.hide(currentFragment);
}
Fragment fragmentTemp = mFragmentManager.findFragmentByTag(tagFragmentName);
if (fragmentTemp == null) {
fragmentTemp = fragment;
fragmentTransaction.add(R.id.frame_layout, fragmentTemp, tagFragmentName);
} else {
fragmentTransaction.show(fragmentTemp);
}
fragmentTransaction.setPrimaryNavigationFragment(fragmentTemp);
fragmentTransaction.setReorderingAllowed(true);
fragmentTransaction.commitNowAllowingStateLoss();
}
And this is how i use it
private void initViews() {
BottomNavigationView bottomNavigationView = findViewById(R.id.navigation);
bottomNavigationView.setOnNavigationItemSelectedListener
(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.explore:
changeFragment(new ExploreFragment(), ExploreFragment.class
.getSimpleName());
toggleViews(true, "");
break;
case R.id.favorite:
changeFragment(new FavoriteFragment(), FavoriteFragment.class
.getSimpleName());
toggleViews(false, "Favorites");
break;
case R.id.venue:
changeFragment(new VenueFragment(), VenueFragment.class.getSimpleName());
toggleViews(false, "Venues");
break;
case R.id.profile:
changeFragment(new ProfileFragment(), ProfileFragment.class
.getSimpleName());
toggleViews(false, "Profile");
break;
}
return true;
}
});
//Manually displaying the first fragment - one time only
changeFragment(new ExploreFragment(), ExploreFragment.class
.getSimpleName());
}
I wrote an Extension function in Kotlin for the same.
fun FragmentManager.switch(containerId: Int, newFrag: Fragment, tag: String) {
var current = findFragmentByTag(tag)
beginTransaction()
.apply {
//Hide the current fragment
primaryNavigationFragment?.let { hide(it) }
//Check if current fragment exists in fragmentManager
if (current == null) {
current = newFrag
add(containerId, current!!, tag)
} else {
show(current!!)
}
}
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.setPrimaryNavigationFragment(current)
.setReorderingAllowed(true)
.commitNowAllowingStateLoss()
}
Try this :
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment fragment = null;
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.container);
switch (item.getItemId()) {
case R.id.action_one:
// Switch to page one
if (!(currentFragment instanceof FragmentA)) {
fragment = FragmentA.newInstance();
}
break;
case R.id.action_two:
// Switch to page two
if (!(currentFragment instanceof FragmentB)) {
fragment = FragmentB.newInstance();
}
break;
case R.id.action_three:
// Switch to page three
if (!(currentFragment instanceof FragmentC)) {
fragment = FragmentC.newInstance();
}
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "TAG").commit();
return true;
}
});
That will get the current fragment in your container and if you click again on this fragment that will not re add the fragment.
Be careful when using replace. Even if providing a fragment that already exists in memory, replace will restart the fragment's lifecycle. To avoid a restart, the transaction object's methods includes add, show, and hide, which can be used to show the correct fragment without restarting it.
private fun switchFragment(selectedTabIndex: Int) {
val previousTabIndex = this.currentTabIndex
this.currentTabIndex = selectedTabIndex
val transaction = supportFragmentManager.beginTransaction()
val tag = fragments[this.currentTabIndex].tag
// if the fragment has not yet been added to the container, add it first
if (supportFragmentManager.findFragmentByTag(tag) == null) {
transaction.add(R.id.container, fragments[this.currentTabIndex], tag)
}
transaction.hide(fragments[previousTabIndex])
transaction.show(fragments[this.currentTabIndex])
transaction.commit()
}
How To stop recreating Fragment when it is Already Visible Using BottomNavigationView
Step 1--
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment fragment = null;
String valuestring;
**if (item.getItemId() == lastSelectedItemId) { // added this
Log.e( "both id is same","LULL" );
return true;
}**
switch (item.getItemId()) {
case R.id.navigation_category:
SetActioBarText( getString( R.string.label_actionbar_categories ) );
fragment = new CategoryFragment();
valuestring = "category";
break;
case R.id.navigation_favourite:
SetActioBarText( getString( R.string.label_actionbar_favourites ) );
fragment = new FavouriteFragment();
valuestring = "favourites";
break;
default:
throw new IllegalStateException( "Unexpected value: " + menuItem.getItemId() );
}
return loadFragment( fragment, valuestring ,menuItem);
}
Now Step 2---
private boolean loadFragment(Fragment fragment, String argument,MenuItem item) {
if (fragment != null) {
transaction = fragmentManager.beginTransaction();
transaction.addToBackStack( argument );
transaction.setTransition( FragmentTransaction.TRANSIT_FRAGMENT_FADE );
transaction.replace( R.id.frame_container, fragment, "demofragment").commitAllowingStateLoss();
lastSelectedItemId= item.getItemId();
return true;
}
return false;
}