Android DialogFragment无法关闭

6

我在Android上有一个自定义对话框,在onCreateView方法中创建了对话框视图。

public class FiltroDialog extends DialogFragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

当我尝试关闭对话框时,我有一个在对话框内通过onClick监听器调用的方法。
boton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
                            Log.d(TAG,"doDismiss");
            FiltroDialog.this.dismiss();
        }
    });

我已经重写了对话框的几个onMethod方法,以便查看对话框发生了什么。

@Override
public void onDestroyView() {
    super.onDestroyView();
    Log.d(TAG, "onDestroyView");
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    Log.d(TAG, "onAttach");
}

@Override
public void onDetach() {
    super.onDetach();
    Log.d(TAG, "onDetach");
}

@Override
public void onStart() {
    super.onStart();
    Log.d(TAG, "onStart");
}

@Override
public void onStop() {
    super.onStop();
    Log.d(TAG, "onStop");
}

    @Override
public void onCancel(DialogInterface dialog) {
    super.onCancel(dialog);
    Log.d(TAG,"onCancel");
}

@Override
public void onDismiss(DialogInterface dialog) {
    super.onDismiss(dialog);
    Log.d(TAG,"onDismiss");
}

我尝试使用 FragmentTransaction 中的 dismiss(); dismissAllowingStateLoss(); 关闭对话框,但每次都得到相同的结果。
D/FiltroDialog(30492): doDismiss
D/FiltroDialog(30492): onStop
D/FiltroDialog(30492): onDestroyView
D/FiltroDialog(30492): onDetach

但是对话框没有从屏幕上消失,使用返回按钮可以正确地使对话框消失,但是使用 dismiss() 或 FragmentTransaction.remove 方法只能到达 Stop、DestroyView 和 Detach,而无法进入 onDismiss()。

当我再次单击按钮时,只有这个在 LogCat 中显示:

D/FiltroDialog(30492): doDismiss

我尝试了几种方法来关闭对话框。以下是我在活动中使用的代码来显示对话框(也尝试过从片段中显示)。
FiltroDialog newFragment = FiltroDialog.newInstance();
newFragment.show(getSupportFragmentManager(), TAG_DLG_FILTROS); 

以下是尝试从活动中关闭对话框的代码(同样在片段中尝试,结果相同):

DialogFragment prev = (DialogFragment) getSupportFragmentManager().findFragmentByTag(TAG_DLG_FILTROS);
if (prev != null) {
    prev.dismiss();         
}

这里是另一次尝试从活动中关闭的尝试(也尝试了从片段中关闭,结果相同)

Fragment prev = getSupportFragmentManager().findFragmentByTag(TAG_DLG_FILTROS);
        if (prev != null) {
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.remove(prev);
            ft.commit();
    }

这里又尝试关闭对话框,并且在DialogFragment中调用对话框的cancel()方法。

boton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {               
            Log.d(TAG,"doDismiss");
            FiltroDialog.this.getDialog().cancel();
        }
    });

不要关闭对话框,也不要调用onDismiss、Stop、DestroyView和Detach方法。

以下是另一种尝试通过在DialogFragment中调用对话框的dismiss()方法来关闭对话框的方法。

boton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {               
            Log.d(TAG,"doDismiss");
            FiltroDialog.this.getDialog().dismiss();
        }
    });

这个问题是由于在应用中的对话框没有被正确处理导致的。具体来说,它既没有调用onDismiss方法,也没有停止、销毁视图或分离方法。

我在应用中有一些对话框,以前从未遇到过这个问题。虽然我不是完全的Android编程新手,但我不知道我做错了什么。这是兼容库中的一个bug吗?


1
你确定已经调用了boton.setOnClickListener吗? - Blackbelt
是的,在onClickListner中,我放置了一个Log.d()调用以确保。 - Angel Ivorra
而且如果您尝试多次解除它会怎么样? - Blackbelt
在调用dismiss方法之后,如果再次点击按钮,会出现nullPointerException异常,因为对话框内的getView()方法返回了null。第二次点击没有任何效果。 - Angel Ivorra
如果你调用cancell而不是dismiss,会有什么区别吗? - Blackbelt
DialogFragment没有cancel()方法,我必须使用getDialog().cancel()或者getDialog().dismiss()。我尝试了两个方法,并更新了问题,但是没有调用onStop、onDismiss等任何方法。 - Angel Ivorra
6个回答

4
我今天遇到了同样的问题。
你是如何处理对话框中的视图的?对我来说,问题在于我有一个FrameLayout,在其中充气视图(根据一些信息)。我不能确定为什么会出现这个问题,但它确实出现了。当我用简单的viewstub代替framelayout时,它完美地工作了。
希望能解决问题。祝好运!

我也处于同样的情况。你所说的“ViewStub”是什么意思? - Gianluca P.
6
使用(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)代替android.support.v4.app.DialogFragment.getLayoutInflater(Bundle)似乎可以正常工作。很酷!在后者的Javadoc中,注释中还有一个"@hide",因此我认为这只是一个不应该使用的功能。 - Gianluca P.
1
奇怪,确实是LayoutInflater引起了这个问题! - Peterdk

0

将 Gianluca P. 的评论转换为答案:

似乎使用错误的 LayoutInflater 可能会破坏解除功能。如果您从 android.support.v4.app.DialogFragment.getLayoutInflater(Bundle) 获取 LayoutInflater,然后使用它来填充视图,则解除操作将被破坏。

要解决此问题,请改用 (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)

这只是 Android 中的一件小事情。


0

嗯,看不出来为什么不起作用,但你可以暂时使用getActivity().onBackPressed()作为一种解决办法。


1
我知道,但我正在寻找的是解决方案或解释,我将对话框更改为片段以实现相同的结果,但我正在开发一个大型Android应用程序,这些事情让我感到非常害怕。无论如何,感谢您的回复。 - Angel Ivorra

0
从@zoltish的答案开始,我发现在创建实际视图后将视图膨胀到对话框内容中会导致这种问题。 在onCreate中,我正在膨胀布局,然后使用post来调用一个onViewCreated工具,在其中在第一个布局中膨胀另一个布局。 解决方案是所有布局/视图层次结构必须从onCreate中加载,至少在4.3模拟器上。

0
我曾经也遇到了同样的问题,后来我把DialogFragment的引用移到了一个方法的本地范围内,这对我起到了作用。(最初,它在我的类字段中)。

0

为什么不尝试只使用这段代码:

dismiss();

如果您想通过 Dialog Fragment 自身来关闭它,您可以在您想要关闭对话框的 Dialog Fragment 中简单地放置以下代码。
例如:
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        dismiss();
    }
});

这将关闭当前显示在屏幕上的最近对话框片段。

希望对您有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接