Cannot get DialogFragment to dismiss programmatically

為{幸葍}努か 提交于 2019-12-04 01:32:49

问题


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");
    }
}

}

回答1:


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;



回答2:


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();
    }



回答3:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!