I'm managing fragments in the Navigation Drawer activity and I'm handling onBackPressed method in order to have a logic "back press" button. The code for the method is this:
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
else if(getSupportFragmentManager().findFragmentByTag("Aprender").isVisible()){
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new Inicio()).commit();
}
else if(getSupportFragmentManager().findFragmentByTag("Practicar").isVisible()){
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new Inicio()).commit();
}
else if(getSupportFragmentManager().findFragmentByTag("Campo").isVisible()){
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new Inicio()).commit();
}
else if(getSupportFragmentManager().findFragmentByTag("Examinar").isVisible()){
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new Inicio()).commit();
}
else if(getSupportFragmentManager().findFragmentByTag("Materias").isVisible()){
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new Inicio()).commit();
}
else if(getSupportFragmentManager().findFragmentByTag("Utilidades").isVisible()){
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new Inicio()).commit();
}
else if(getSupportFragmentManager().findFragmentByTag("Info").isVisible()){
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new Inicio()).commit();
}
else {
moveTaskToBack(true);
}
}
This should make sense due to that I have another method which stores the tag when replacing fragments:
private void displaySelectedScreen(int itemId) {
//creating fragment object
Fragment fragment = null;
//initializing the fragment object which is selected
switch (itemId) {
case R.id.nav_inicio:
fragment = new Inicio();
break;
case R.id.nav_aprender:
fragment = new Aprender();
break;
case R.id.nav_practicar:
fragment = new Practicar();
break;
case R.id.nav_examinar:
fragment = new Examinar();
break;
case R.id.nav_materias:
fragment = new Materias();
break;
case R.id.nav_utilidades:
fragment = new Utilidades();
break;
case R.id.nav_info:
fragment = new Info();
break;
}
//replacing the fragment
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment, fragment.getClass().getCanonicalName().substring(44));
ft.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
}
The reason of writing fragment.getClass().getCanonicalName().substring(44) is just because it is the way to set a tag which is equal to the class name (for example: "Aprender"), and it is 44 because it is the number of characters I have before in the package name (com.myname.myapp.) and in fact it works properly for "Aprender" fragment as I will explain:
The problem comes when I run the app. If I enter from my main fragment (Inicio) into the "Aprender" fragment and then press back button, it works with no problem at all, so it goes to the main fragment (Inicio). But for some reason I cannot understand, it does not work properly with the other cases (Practicar, Examinar, etc.). I ran with logcat activated and this is the error:
E/InputEventSender: Exception dispatching finished signal.
E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
E/MessageQueue-JNI: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.support.v4.app.Fragment.isVisible()' on a null object reference
I would really thank any clarification to this and a proper solution to solve this situation. If necessary, just let me know any question.
Replace your each if condition with below.
Fragment fragment = getSupportFragmentManager().findFragmentByTag("Aprender");
if(fragment != null){
fragment.isVisible();
do your stuff
}
you was getting null pointer as fragment you where looking was removed from memory so make null check each time you are searching fragment using findFragmentByTag method