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