I have a scenario where I show a DialogFragment
(using getSupportFragmentManager()
) that shows a list of values and an "Add" button. If the user clicks the add button, I display another DialogFragment
(using getChildFragmentManager()
that consists of an EditText
and Button
. When the user clicks the new Button
if the value passes validation, I add it to the list. If it doesn't pass validation, I show another DialogFragment
that displays an error message, and an "OK" button. I would like it that when the "OK" button is pressed, the user will still see the DialogFragment
with the EditText
and Button
so that they could look over the bad value and possibly change it. However, when the "OK" button is pressed in the error message DialogFragment
, the dialog is dismissed, and only the original DialogFragment
(the one with the list of values) is displayed.
How would I keep the second DialogFragment
still displayed after the third one is dismissed?
EDIT: Here are some code snippets:
//clicking this button shows the first ("outer") fragment
findViewById(R.id.voicemail_notifications_email_addresses).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
AddressListDialog.newInstance(
line, AddressListDialog.VOICEMAIL_NOTIFICATIONS_EMAIL)
.show(((FragmentActivity)getContext()).getSupportFragmentManager(), "dialog");
}
});
public static class AddressListDialog extends DialogFragment {
public AddressListDialog() {}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View v = LayoutInflater.from(getActivity()).inflate(R.layout.vm_address_list_dialog, null);
ListView lv = (ListView) v.findViewById(R.id.voicemail_notifications_address_list);
final AddressAdapter adapter = new AddressAdapter();
lv.setAdapter(adapter);
v.findViewById(R.id.voicemail_add_address_button).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//first child fragment
AddAddressDialog.newInstance(getType()).setAdapter(adapter)
.show(getChildFragmentManager(), "dialog");
}
});
Dialog d = new AlertDialog.Builder(getActivity())
.setTitle(titleRes)
.setView(v)
.setPositiveButton(R.string.global_dialog_pos, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
}
)
.create();
return d;
}
private class AddressAdapter extends BaseAdapter {
.
.
.
public boolean add(LineVoicemailInfo.VmContact contact) {
if(addresses.size() >= 3) {
return false;
}
else if(!contact.isValid(isEmailType())) {
return true;
}
else {
addresses.add(contact);
notifyDataSetChanged();
return true;
}
}
public static class AddAddressDialog extends DialogFragment {
private AddressAdapter adapter;
public AddAddressDialog() {}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
DialogInterface.OnClickListener onPosClick = null;
final View v;
v = LayoutInflater.from(getActivity()).inflate(R.layout.voicemail_add_email_address, null);
onPosClick = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
LineVoicemailInfo.VmContact contact = new LineVoicemailInfo.VmContact(((EditText)v.findViewById(R.id.voicemail_add_email_address)).getText().toString());
if(!adapter.add(contact)) {
//second child fragment
BadAddressDialog.newInstance("Not a valid address")
.show(getChildFragmentManager(), "dialog");
}
}
};
Dialog d = new AlertDialog.Builder(getActivity())
.setTitle("Add Address")
.setView(v)
.setCancelable(false)
.setPositiveButton(R.string.voicemail_addresses_add, onPosClick)
.setNegativeButton(R.string.global_dialog_neg, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
})
.create();
setCancelable(false);
return d;
}
}
public static class BadAddressDialog extends DialogFragment {
public BadAddressDialog() {}
public static BadAddressDialog newInstance(String message) {
BadAddressDialog frag = new BadAddressDialog();
Bundle args = new Bundle();
args.putString("message", message);
frag.setArguments(args);
return frag;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String message = getArguments().getString("message");
Dialog d = new AlertDialog.Builder(getActivity())
.setTitle("Error adding address")
.setMessage(message)
.setCancelable(false)
.setPositiveButton(R.string.global_dialog_pos, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
})
.create();
setCancelable(false);
return d;
}
}
I suppose the problem is that you use standard show
method for displaying dialogs. According to Android sources, this method does not add fragment to backstack, so then the top-most dialog is dismissed, the middle is dismissed as well.
You should begin trasaction on your own before calling show
and add the transaction to backstack (call addToBackStack
). An example is shown on DialogFragment documentation page.