APP & program

关于安卓DialogFragment使用(三)

2023-03-04  本文已影响0人  motosheep

本文将介绍dialog fragment在使用过程中反复出现的问题。

当使用dialog fragment时,在重写了getDialog的dismiss的监听时。取消弹窗,退出页面,重新进入,会导致dialogfragment重新出现。

通过排查发现,若代码中主动调用了dismiss,则不会出现该bug,否则会出现这种情况。

对于出现这种情况的原因,可以追查源码发现如下:
(一)首先,观察setOnDismissListener是一个单对象监听,换而言之,重写会进行覆盖。

    /**
     * Set a listener to be invoked when the dialog is dismissed.
     * @param listener The {@link DialogInterface.OnDismissListener} to use.
     */
    public void setOnDismissListener(@Nullable OnDismissListener listener) {
        if (mCancelAndDismissTaken != null) {
            throw new IllegalStateException(
                    "OnDismissListener is already taken by "
                    + mCancelAndDismissTaken + " and can not be replaced.");
        }
        if (listener != null) {
            mDismissMessage = mListenersHandler.obtainMessage(DISMISS, listener);
        } else {
            mDismissMessage = null;
        }
    }

(二)第二,追查dialogfragment的源码,发现有以下代码:

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        if (!mShowsDialog) {
            return;
        }

        View view = getView();
        if (view != null) {
            if (view.getParent() != null) {
                throw new IllegalStateException(
                        "DialogFragment can not be attached to a container view");
            }
            mDialog.setContentView(view);
        }
        final Activity activity = getActivity();
        if (activity != null) {
            mDialog.setOwnerActivity(activity);
        }
        mDialog.setCancelable(mCancelable);
        mDialog.setOnCancelListener(this);
        mDialog.setOnDismissListener(this);
        if (savedInstanceState != null) {
            Bundle dialogState = savedInstanceState.getBundle(SAVED_DIALOG_STATE_TAG);
            if (dialogState != null) {
                mDialog.onRestoreInstanceState(dialogState);
            }
        }
    }

发现在onActivityCreated方法中,会调用一次setOnDismissListener。假如我们重写的基类中,且在onActivityCreated生命周期后,通过getDialog()方法重写了setOnDismissListener,那么原始的dialog定义好的setOnDismissListener就会失效,导致文章开始说的bug出现。

这里解决方法有很多,提供一下思路:
(一)如果外部一定要设置dialog的setOnDismissListener监听,这个时候,需要在该方法内,调用一次dismiss()方法确保dialog fragment真正走了"消失"的方法。
(二)子类重写onDismiss()方法,该方法是DialogInterface.OnDismissListener的实现方法,当dialog取消的时候,会进行回调。
总的来所,推荐使用第二种方法,能减少意外情况发生。

that's all--------------------------------------------------------------------------------------

上一篇 下一篇

猜你喜欢

热点阅读