Bottomnavigationview - How to Avoid Recreation of Fragments and Reuse Them

BottomNavigationView - How to avoid recreation of Fragments and reuse them

I had similar issue, but this code solved my problem.

public class MainActivity extends AppCompatActivity {

boolean doubleBackToExitPressedOnce = false;
final Fragment fragment1 = new HomeFragment();
final Fragment fragment2 = new DashboardFragment();
final Fragment fragment3 = new NotificationsFragment();
final FragmentManager fm = getSupportFragmentManager();
Fragment active = fragment1;
BottomNavigationView navigation;

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

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
setFragment(fragment1, "1", 0);
}


private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
setFragment(fragment1, "1", 0);
return true;
case R.id.navigation_dashboard:
setFragment(fragment2, "2", 1);
return true;
case R.id.navigation_notifications:
setFragment(fragment3, "3", 2);
return true;
}
return false;
}
};

public void setFragment(Fragment fragment, String tag, int position) {
if (fragment.isAdded()) {
fm.beginTransaction().hide(active).show(fragment).commit();
} else {
fm.beginTransaction().add(R.id.main_container, fragment, tag).commit();
}
navigation.getMenu().getItem(position).setChecked(true);
active = fragment;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();

if (id == R.id.action_settings) {
startActivity(new Intent(MainActivity.this, SettingsActivity.class));
return true;
}

return super.onOptionsItemSelected(item);
}

@Override
public void onBackPressed() {
if (active == fragment1) {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();
} else {
setFragment(fragment1, "1", 0);
}
}
}

Avoid creating the fragments again using BottomNavigationView

Use this code to open your fragment. Your fragment will not create every time. It will get same fragment from stack if exist.

/**
* replace or add fragment to the container
*
* @param fragment pass android.support.v4.app.Fragment
* @param bundle pass your extra bundle if any
* @param popBackStack if true it will clear back stack
* @param findInStack if true it will load old fragment if found
*/
public void replaceFragment(Fragment fragment, @Nullable Bundle bundle, boolean popBackStack, boolean findInStack) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
String tag = fragment.getClass().getName();
Fragment parentFragment;
if (findInStack && fm.findFragmentByTag(tag) != null) {
parentFragment = fm.findFragmentByTag(tag);
} else {
parentFragment = fragment;
}
// if user passes the @bundle in not null, then can be added to the fragment
if (bundle != null)
parentFragment.setArguments(bundle);
else parentFragment.setArguments(null);
// this is for the very first fragment not to be added into the back stack.
if (popBackStack) {
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} else {
ft.addToBackStack(parentFragment.getClass().getName() + "");
}
ft.replace(R.id.contenedor_principal, parentFragment, tag);
ft.commit();
fm.executePendingTransactions();
}

use it like

Update :

If your fragment is home or dashboard fragment then

Fragment f = new YourFragment();
replaceFragment(f, null, true, true);

Otherwise

Fragment f = new YourFragment();
replaceFragment(f, null, false, true);

Important This code is not replacement of saving all states or variables in fragment. This code will useful because it will not create fragment instance again.

For saving all states and variables in fragment for future use see this answer

Prevent fragment refreshing with bottom navbar

The problem is that you are creating a new instance every time. You can cache the instance like:

    private Fragment mHomeFragment = new HomeFragment();
private Fragment mDashboardFragment = new DashboardFragment();
private Fragment mNotificationsFragment = new NotificationsFragment();


@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment fragment = null;

switch (item.getItemId()) {
case R.id.navigation_home:
fragment = mHomeFragment;
break;

case R.id.navigation_dashboard:
fragment = mDashboardFragment;
break;

case R.id.navigation_notifications:
fragment = mNotificationsFragment;
break;

}

return loadFragment(fragment);
}


Related Topics



Leave a reply



Submit