I have a DialogFragment that shows a list of items to pick from (similar to the attach dialog in Messaging).
My problem is that I cannot get this dialog to dismiss when an item is selected. I've tried calling dismiss()
and getDialog().dismiss()
inside the OnItemClickListener
, no luck. I've tried to remove the dialog through the FragmentManager, I've tried fragmentManager.popBackStack()
, all to no avail. I cannot get this dialog to dismiss. It goes away fine when clicking outside the dialog or hitting the back button, but nothing in my code will make it go away.
Has anyone seen this before? How do I get the dialog to dismiss correctly?
Dialog Code:
public class ShareDialog extends DialogFragment {
public enum ShareType {
Camera, Gallery, Web, Whiteboard, Browse,
}
BaseAdapter mShareAdapter = new BaseAdapter() {
@Override
public View getView(int position, View contentView, ViewGroup parent) {
TextView view = null;
if (contentView == null) {
view = (TextView) getLayoutInflater(null).inflate(android.R.layout.simple_list_item_1, parent, false);
} else {
view = (TextView) contentView;
}
int draw = 0;
switch (ShareType.values()[position]) {
case Browse:
view.setText("Browse Content...");
draw = R.drawable.ic_share_browse;
break;
case Camera:
view.setText("Image from Camera...");
draw = R.drawable.ic_share_camera;
break;
case Gallery:
view.setText("Image from Gallery...");
draw = R.drawable.ic_share_gallery;
break;
case Web:
view.setText("New Browsing Session");
draw = R.drawable.ic_share_web;
break;
case Whiteboard:
view.setText("New Whiteboard");
draw = R.drawable.ic_share_whiteboard;
break;
}
view.setCompoundDrawablesWithIntrinsicBounds(draw, 0, 0, 0);
view.setCompoundDrawablePadding(8);
return view;
}
@Override
public long getItemId(int position) {
return ShareType.values()[position].ordinal();
}
@Override
public Object getItem(int position) {
return ShareType.values()[position];
}
@Override
public int getCount() {
return ShareType.values().length;
}
};
public Dialog onCreateDialog(android.os.Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Share which?");
ListView list = new ListView(getActivity());
list.setAdapter(mShareAdapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long itemId) {
dismiss(); // WHY DOESN'T THIS WORK???
if (listener != null)
listener.newShare((ShareType) mShareAdapter.getItem(position));
}
});
builder.setView(list);
return builder.create();
}
public interface ShareDialogListener {
void newShare(ShareType type);
}
private ShareDialogListener listener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Verify that the host activity implements the callback interface
try {
// Instantiate the AutoconnectListener so we can send events to the host
listener = (ShareDialogListener) activity;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString() + " must implement ShareDialogListener");
}
}
}
For some - unknown to me - reason, the dialog reference you get back from getDialog() isn't the one you want to work with when inside the listener. You need a reference to the dialog as provided you when you call builder.create();
For example:
final AlertDialog dialog = builder.create();
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
dialog.dismiss();
}
});
return dialog;
Why not use the methods available on AlertDialog.Builder to build the list, instead of creating your own ListView and populating it?
I have modified your sample code to show how this would work, and in this example the dialog dismiss() functions fine.
public Dialog onCreateDialog(android.os.Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setSingleChoiceItems(mShareAdapter, 0, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if (listener != null) {
listener.newShare((ShareType) mShareAdapter.getItem(which));
}
}
});
builder.setTitle("Share which?");
return builder.create();
}
HA....
I've found it...
The reason for this is actually ours... we were trying to inflate an xml, and have called:
DialogFragment.this.getLayoutInflater(null).inflate(...);
This call causes, like I've stated in the comment to create 4 dialogs, and then everything gets messed up.
The proper way to do this would be to call:
LayoutInflater layoutInflater = (LayoutInflater) getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(...);
This fix solved the annoying bug for me on the first go!
来源:https://stackoverflow.com/questions/14738572/cannot-get-dialogfragment-to-dismiss-programmatically