Android 无法获取DialogFragment以编程方式关闭

Android 无法获取DialogFragment以编程方式关闭,android,android-fragments,android-dialogfragment,Android,Android Fragments,Android Dialogfragment,我有一个DialogFragment,它显示了要从中选择的项目列表(类似于消息传递中的“附加”对话框) 我的问题是,当选择某个项目时,我无法关闭此对话框。我已尝试在OnItemClickListener中调用Disclease()和getDialog().Disclease(),运气不好。我试图通过FragmentManager删除该对话框,我尝试了FragmentManager.popbackbackstack(),但都没有成功。我无法取消此对话框。在对话框外单击或单击“上一步”按钮时,它会很

我有一个DialogFragment,它显示了要从中选择的项目列表(类似于消息传递中的“附加”对话框)

我的问题是,当选择某个项目时,我无法关闭此对话框。我已尝试在
OnItemClickListener
中调用
Disclease()
getDialog().Disclease()
,运气不好。我试图通过FragmentManager删除该对话框,我尝试了
FragmentManager.popbackbackstack()
,但都没有成功。我无法取消此对话框。在对话框外单击或单击“上一步”按钮时,它会很好地消失,但代码中的任何内容都不会使它消失

以前有人见过这个吗?如何使对话框正确关闭

对话框代码:

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

}
公共类ShareDialog扩展了DialogFragment{
公共枚举共享类型{
摄像头、多媒体资料、网络、白板、浏览、,
}
BaseAdapter mShareAdapter=新BaseAdapter(){
@凌驾
公共视图getView(int位置、视图contentView、视图组父级){
TextView=null;
if(contentView==null){
视图=(TextView)getLayoutFlater(null).充气(android.R.layout.simple\u list\u item\u 1,父项,false);
}否则{
视图=(TextView)contentView;
}
int-draw=0;
开关(ShareType.values()[位置]){
案例浏览:
view.setText(“浏览内容…”);
draw=R.drawable.ic\u share\u browse;
打破
箱式摄像机:
view.setText(“来自照相机的图像…”);
draw=R.drawable.ic_share_摄像头;
打破
案例库:
view.setText(“来自图库的图像…”);
draw=R.drawable.ic\u share\u gallery;
打破
案例网站:
view.setText(“新浏览会话”);
draw=R.drawable.ic\u share\u web;
打破
案例白板:
view.setText(“新白板”);
draw=R.drawable.ic\u share\u白板;
打破
}
view.setCompoundDrawablesWithIntrinsicBounds(draw,0,0,0);
视图。setCompoundDrawablePadding(8);
返回视图;
}
@凌驾
公共长getItemId(int位置){
返回ShareType.values()[position].ordinal();
}
@凌驾
公共对象getItem(int位置){
返回ShareType.values()[position];
}
@凌驾
public int getCount(){
返回ShareType.values().length;
}
};
创建对话框上的公共对话框(android.os.Bundle savedInstanceState){
AlertDialog.Builder=新建AlertDialog.Builder(getActivity());
builder.setTitle(“共享哪个?”);
ListView list=新建ListView(getActivity());
list.setAdapter(mShareAdapter);
list.setOnItemClickListener(新的AdapterView.OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父项、视图、整型位置、长项目ID){
Disclose();//为什么这个不起作用???
if(侦听器!=null)
newShare((ShareType)mShareAdapter.getItem(position));
}
});
builder.setView(列表);
返回builder.create();
}
公共接口ShareDialogListener{
作废新闻共享(共享类型);
}
私有共享对话侦听器;
@凌驾
公共事务主任(活动){
超级转速计(活动);
//验证主机活动是否实现了回调接口
试一试{
//实例化AutoconnectListener,以便将事件发送到主机
listener=(ShareDialogListener)活动;
}catch(ClassCastException e){
//活动未实现接口,引发异常
抛出新的ClassCastException(activity.toString()+“必须实现ShareDialogListener”);
}
}
}

为什么不使用AlertDialog.Builder上提供的方法来构建列表,而不是创建自己的ListView并填充它

我已经修改了您的示例代码,以说明这是如何工作的,在本例中,dialog dismise()功能很好

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

出于某种我不知道的原因,从getDialog()返回的对话框引用不是您在侦听器中要使用的引用。调用builder.create()时,需要提供对对话框的引用

例如:

    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;
final AlertDialog=builder.create();
list.setOnItemClickListener(新的AdapterView.OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父对象、视图、整型位置、长id){
dialog.dismise();
}
});
返回对话框;
HA

我找到了

原因其实是我们的。。。我们试图膨胀xml,并调用:

DialogFragment.this.getLayoutInflater(null).inflate(...);
正如我在评论中所说,这个调用会导致创建4个对话框,然后一切都会变得一团糟

正确的方法是调用:

LayoutInflater layoutInflater = (LayoutInflater) getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(...);

这个补丁一开始就为我解决了恼人的bug

谢谢大家!!我不敢相信我错过了那个选择。有趣的是(因为我尝试过)注意到
DialogFragment.dismise()
是不够的,我必须在DialogInterface上调用它。不知道为什么。我注意到onDialogCreated方法被调用了4次,每次都创建一个新的对话框实例。。。在onItemClickListener中,与getDialog一起返回的对话框是最后一个对话框,对其调用Disclease或cancel不会产生任何效果!您可以在此处阅读: