Hammad Nasir Hammad Nasir - 2 months ago 13
Java Question

App crashing giving 'java.lang.IllegalStateException' when opening a dialog again after closing it

I have a dialog in which I'm supposed to fill in some details in an

EditText
. If the positive button is clicked when the edit text is empty, a
Snackbar
with a message is shown and the dialog gets closed. But, when I open the dialog again, the app gets crahed giving:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first
error.

Here's how I have inflated the view:

LayoutInflater inflater = this.getLayoutInflater();
addVenueDialog = inflater.inflate(R.layout.add_venue_dialog, null);


and here's the java code behind opening dialog and checking if edit text is empty or not:

case R.id.nav_add_venue:
if (dialog == null) {

LayoutInflater inflater = this.getLayoutInflater();
View addVenueDialog = inflater.inflate(R.layout.add_venue_dialog, null);

vName = (EditText) addVenueDialog.findViewById(R.id.vName);
vAddress = (EditText) addVenueDialog.findViewById(R.id.vAddress);

AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Title");
builder.setView(addVenueDialog);
builder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (isNetworkAvailable()) {
if (vName.getText().toString().isEmpty()) {
Snackbar snackbar = Snackbar
.make(coordinatorLayout, "V name cannot be empty", Snackbar.LENGTH_SHORT);
snackbar.show();
} else if (vAddress.getText().toString().isEmpty()) {
Snackbar snackbar = Snackbar
.make(coordinatorLayout, "V address cannot be empty", Snackbar.LENGTH_SHORT);
snackbar.show();
} else {
mDatabase.child("vs").child(user.getUid()).child("V name").setValue(vName.getText().toString());
mDatabase.child("vs").child(user.getUid()).child("V address").setValue(vAddress.getText().toString());
}
} else {
Snackbar snackbar = Snackbar
.make(coordinatorLayout, "No internet connection", Snackbar.LENGTH_SHORT);
snackbar.show();
}
}
});
dialog = builder.create();
}
dialog.show();
break;


I don't know why the app is crashing when I'm opening the dialog once again after closing it.

Please let me know.

Answer

One simple solution would be to keep a global instance of AlertDialog and re-using it:

//global
private AlertDialog dialog;

now in the switch case:

case R.id.nav_add_venue:
    if(dialog == null) {
        LayoutInflater inflater = this.getLayoutInflater(); 
        View addVenueDialog = inflater.inflate(R.layout.add_venue_dialog, null); 

        builder.setView(addVenueDialog); 

        final EditText vName = (EditText) addVenueDialog.findViewById(R.id.vName); 
        final EditText vAddress = (EditText) addVenueDialog.findViewById(R.id.vAddress); 

        // Other code //
        dialog = builder.create();
     }
     dialog.show();
     break;

Remember to dismiss the dialog onDestroy method to avoid memory leak:

public void onDestroy() {
   super.onDestroy();
   if(dialog != null) {
     dialog.dismiss();
   }
 }