Dialog的统一管理

首先我们需要创建一个基类Dialog,方便子dialog进行统一集成

package com.example.commonlib.dialog;


import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import androidx.annotation.AnimRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.example.commonlib.R;

import java.lang.ref.WeakReference;

/**
 * Created by malei on 2019-12-06
 * Describe:
 *
 *该弹出框的特点是:
 * 当有新的弹出框时,会根据久的弹出框的level进行比较,判断是否需要马上展示。
 * 三个弹出框需要展示时候,每次只展示一个,每次消失一个在弹下一个
 *
 */
public abstract class BaseDialogFragment extends DialogFragment implements DialogInterface.OnKeyListener, Comparable<BaseDialogFragment> {

    protected final String TAG = getClass().getSimpleName() + System.currentTimeMillis();
    protected Window mWindow;
    private WeakReference<IInnerDialogCallback> mInnerDialogCallbackRef;
    private WeakReference<IDialogCallback> mDialogCallbackRef;
    protected View mDialogView;
    private boolean mCanceledOnTouchOutside;
    private volatile boolean mIsClosing;
    private volatile boolean mShowNextDialogAfterClosed = true;
    private int mPriorityLevel = DialogPriority.LEVEL_DEFAULT;
    private boolean mDisableEnterAnim;
    private boolean mDisableExitAnim;
    private @AnimRes int mDialogEnterAnimResId = R.anim.dialog_zoom_in;
    private @AnimRes int mDialogExitAnimResId = R.anim.dialog_zoom_out;
    private boolean mDisableBackPress;
    private boolean mEnableFullScreen;

    protected void onShow(){}  //当dialog显示的时候触发
    protected void onConfirm(){}  //确定按钮点击
    protected void onClose(){}   //取消按钮点击
    protected void onBackPressed(){}  //点击back的触发
    protected void onDismiss(){}  //当前dailog消失的时候触发
    protected void clearDisposable() { }  //当点击确定,取消,back,等消失的时候触发

    /**
     * 用于部分定制弹窗在从后台切回前台重新展示时的数据设置
     */
    protected void onDialogInit() {}

    protected abstract View createLayout(@NonNull LayoutInflater inflater,
                                         @Nullable ViewGroup container,
                                         @Nullable Bundle savedInstanceState);
    protected abstract void initView(View dialogView);


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        if (getDialog() == null) {
            Context context = getContext();
            while (context instanceof ContextWrapper) {
                if (context instanceof FragmentActivity) {
                    break;
                }
                context = ((ContextWrapper) context).getBaseContext();
            }
            if (context instanceof FragmentActivity) {
                ((FragmentActivity) context).finish();
                return;
            } else {
                setShowsDialog(false);
            }
        }
        super.onActivityCreated(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mDialogView = createLayout(inflater, container, savedInstanceState);
        initView(mDialogView);
        return mDialogView;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mWindow = getDialog().getWindow();
        if (mWindow != null) {
            mWindow.setWindowAnimations(mDisableEnterAnim ? R.style.dialog_without_anim_style : mDialogEnterAnimResId);
            mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            if (mEnableFullScreen) {
                mWindow.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
            }
        }
        getDialog().setOnKeyListener(this);
    }

    public View getDialogView() {
        return mDialogView;
    }

    public void enableFullScreen(boolean enableFullScreen) {
        mEnableFullScreen = enableFullScreen;
    }

    /**
     * @Time: 2019-12-06 16:23
     * @Des: 点击周边是否消失
     */
    public BaseDialogFragment setCanceledOnTouchOutside(boolean canceledOnTouchOutside) {
        mCanceledOnTouchOutside = canceledOnTouchOutside;
        return this;
    }

    /**
     * @Time: 2019-12-06 16:24
     * @Des: 是否可以点击返回键
     */
    public BaseDialogFragment disableBackPress(boolean disableBackPress) {
        mDisableBackPress = disableBackPress;
        return this;
    }

    @Override
    public void onStart() {
        super.onStart();
        mWindow = getDialog().getWindow();
        if (mWindow != null) {
            mWindow.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
            int width = ViewGroup.LayoutParams.MATCH_PARENT;
            int height = ViewGroup.LayoutParams.MATCH_PARENT;
            mWindow.setLayout(width, height);
            mWindow.setGravity(Gravity.CENTER);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        getDialog().setCanceledOnTouchOutside(mCanceledOnTouchOutside);
    }

    @Override
    @SuppressLint("RestrictedApi")
    public void setupDialog(Dialog dialog, int style) {
        super.setupDialog(dialog, STYLE_NO_FRAME);
    }

    /**
     * 按全局优先级统一管理弹窗
     */
    public final void show() {
        DialogManager.INSTANCE.showDialog(this);
    }

    /**
     * NOTE: 外部直接调用此方法则对应dialog不受统一调配,如需要使用优先级统一调配,请使用{@link #show()}
     */
    public void show(FragmentManager manager, String tag) {
        if (manager == null || manager.isDestroyed() || manager.isStateSaved()) {
            return;
        }
        super.show(manager, TextUtils.isEmpty(tag) ? TAG : tag);
        onShow();
        if (mDialogCallbackRef != null) {
            IDialogCallback callback = mDialogCallbackRef.get();
            if (callback != null) {
                callback.onShow();
            }
        }
    }

    /**
     * NOTE: 外部直接调用此方法则对应dialog不受统一调配,如需要使用优先级统一调配,请使用{@link #show()}
     */
    public void showAllowingStateLoss(FragmentManager manager, String tag) {
        try {
            FragmentTransaction ft = manager.beginTransaction();
            String tagV = TextUtils.isEmpty(tag) ? TAG : tag;
            if (!isAdded() && null == manager.findFragmentByTag(tagV)) {
                ft.add(this, tagV);
            } else {
                ft.show(this);
            }
            ft.commitAllowingStateLoss();
            manager.executePendingTransactions();

            onShow();
            if (mDialogCallbackRef != null) {
                IDialogCallback callback = mDialogCallbackRef.get();
                if (callback != null) {
                    callback.onShow();
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (mDisableBackPress) {
                return true;
            }
            if (!mIsClosing) {
                clearDisposable();
                if (mDialogCallbackRef != null) {
                    IDialogCallback callback = mDialogCallbackRef.get();
                    if (callback != null) {
                        callback.onBackPressed();
                    }
                }
                onBackPressed();
                closeDialog(true);
                return true;
            }
            return true;
        }
        return false;
    }

    public boolean isClosing() {
        return mIsClosing;
    }

    public BaseDialogFragment setDialogArguments(@Nullable Bundle args) {
        super.setArguments(args);
        return this;
    }

    public BaseDialogFragment disableEnterAnim(boolean disableEnterAnim) {
        mDisableEnterAnim = disableEnterAnim;
        return this;
    }

    public BaseDialogFragment disableExitAnim(boolean disableExitAnim) {
        mDisableExitAnim = disableExitAnim;
        return this;
    }

    public BaseDialogFragment setDialogEnterAnimResId(@StyleRes int dialogEnterAnimResId) {
        mDialogEnterAnimResId = dialogEnterAnimResId;
        return this;
    }

    public BaseDialogFragment setDialogExitAnimResId(@AnimRes int dialogExitAnimResId) {
        mDialogExitAnimResId = dialogExitAnimResId;
        return this;
    }

    /**
     * 自定义dialog请勿使用
     */
    void setInnerDialogCallback(IInnerDialogCallback dialogCallback) {
        if (dialogCallback != null) {
            mInnerDialogCallbackRef = new WeakReference<>(dialogCallback);
        } else {
            mInnerDialogCallbackRef = null;
        }
    }

    /**
     * 自定义dialog选用,需额外回调时使用,否则仅override同名abstract方法即可
     */
    public BaseDialogFragment setDialogCallback(IDialogCallback dialogCallback) {
        if (dialogCallback != null) {
            mDialogCallbackRef = new WeakReference<>(dialogCallback);
        } else {
            mDialogCallbackRef = null;
        }
        return this;
    }

    /**
     * perform confirm button or confirm zone
     * 确定按钮点击
     */
    public void performConfirm() {
        if (mIsClosing) {
            return;
        }
        clearDisposable();
        onConfirm();
        if (mDialogCallbackRef != null) {
            IDialogCallback callback = mDialogCallbackRef.get();
            if (callback != null) {
                callback.onConfirm();
            }
        }
        closeDialog(true);
    }

    /**
     * perform close button or close zone
     * 取消按钮点击
     */
    public void performClose() {
        if (mIsClosing) {
            return;
        }
        clearDisposable();
        onClose();
        if (mDialogCallbackRef != null) {
            IDialogCallback callback = mDialogCallbackRef.get();
            if (callback != null) {
                callback.onClose();
            }
        }
        closeDialog(true);
    }

    void closeDialogForNow() {
        if (getFragmentManager() != null) {
            dismissAllowingStateLoss();
        }
    }

    void closeDialogImmediately() {
        if (mIsClosing) {
            return;
        }
        mIsClosing = true;
        closeDialogImmediately(mShowNextDialogAfterClosed);
    }

    private void closeDialogImmediately(boolean showNextDialog) {
        clearDisposable();
        if (getFragmentManager() != null) {
            dismissAllowingStateLoss();
        }
        if (mDialogCallbackRef != null) {
            IDialogCallback callback = mDialogCallbackRef.get();
            if (callback != null) {
                callback.onDismiss();
            }
            mDialogCallbackRef = null;
        }
        if (mInnerDialogCallbackRef != null) {
            IInnerDialogCallback dialogCallback = mInnerDialogCallbackRef.get();
            if (dialogCallback != null) {
                dialogCallback.onDismiss(showNextDialog);
            }
            mInnerDialogCallbackRef = null;
        }
        onDismiss();
    }

    public void closeDialog(final boolean showNextDialog) {
        if (mIsClosing) {
            return;
        }
        mIsClosing = true;
        mShowNextDialogAfterClosed = showNextDialog;
        if (mDisableExitAnim) {
            closeDialogImmediately(showNextDialog);
        } else {
            if (mDialogView != null) {
                Animation closeAnim = AnimationUtils.loadAnimation(DialogManager.mAppContext, mDialogExitAnimResId);
                closeAnim.setFillAfter(true);
                closeAnim.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        mDialogView.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                closeDialogImmediately(showNextDialog);
                            }
                        }, 50);
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
                    }
                });
                mDialogView.startAnimation(closeAnim);
            } else {
                closeDialogImmediately(showNextDialog);
            }
        }
    }

    /**
     * @Time: 2019-12-06 16:25
     * @Des: 设置级别
     */
    public BaseDialogFragment setPriorityLevel(int priorityLevel) {
        mPriorityLevel = priorityLevel;
        return this;
    }

    public int getPriorityLevel() {
        return mPriorityLevel;
    }

    @Override
    public final int compareTo(BaseDialogFragment dialogFragment) {
        return dialogFragment != null ? Integer.compare(mPriorityLevel, dialogFragment.mPriorityLevel) : 1;
    }
}

2.创建dialog的统一管理类

package com.example.commonlib.dialog;

import android.app.Application;
import android.content.Intent;

import androidx.annotation.NonNull;

import java.lang.ref.WeakReference;
import java.util.concurrent.PriorityBlockingQueue;

/**
 * Created by malei on 2019-12-06
 * Describe:
 */
public enum DialogManager {

    INSTANCE;

    private static final int CUR_CONTAINER_STATE_ON_INIT = 0; // 当前dialog容器处于初始化过程中
    private static final int CUR_CONTAINER_STATE_AVAILABLE = 1; // 当前有可用dialog容器
    private static final int CUR_CONTAINER_STATE_INVALID = 2; // 当前无可用dialog容器
    public static Application mAppContext ;

    private PriorityBlockingQueue<BaseDialogFragment> mDialogFragmentsQueue = new PriorityBlockingQueue<>();

    private WeakReference<DialogActivity> mCurDialogContainer;

    private volatile boolean mIsInterrupted;

    private volatile int mCurContainerState = CUR_CONTAINER_STATE_INVALID;

    DialogManager() {

    }

    public synchronized boolean isNonValidDialog() {
        return mIsInterrupted || mDialogFragmentsQueue.isEmpty();
    }

    public synchronized BaseDialogFragment peekTopDialog() {
        return mDialogFragmentsQueue.peek();
    }

    public synchronized void removeCertainDialog(BaseDialogFragment dialogFragment) {
        if (dialogFragment == null) {
            return;
        }
        mDialogFragmentsQueue.remove(dialogFragment);
    }

    public synchronized void showDialog(@NonNull BaseDialogFragment dialogFragment) {
        mDialogFragmentsQueue.put(dialogFragment);
        tryShowDialog();
    }

    private synchronized void tryShowDialog() {
        if (mIsInterrupted) {
            return;
        }
        if (mCurContainerState == CUR_CONTAINER_STATE_AVAILABLE) {
            triggerShowNextDialog();
        } else if (mCurContainerState == CUR_CONTAINER_STATE_INVALID) {
            if (!mDialogFragmentsQueue.isEmpty()) {
                createNewDialogContainer();
            }
        } else if (mCurContainerState == CUR_CONTAINER_STATE_ON_INIT) {
            // do nothing
        } else {
            // do nothing
        }
    }

    private synchronized void triggerShowNextDialog() {
        if (mCurDialogContainer != null) {
            DialogActivity container = mCurDialogContainer.get();
            if (container != null) {
                container.showNextDialog();
                return;
            }
        }
        mCurContainerState = CUR_CONTAINER_STATE_INVALID;
    }

    private synchronized void createNewDialogContainer() {
        mCurContainerState = CUR_CONTAINER_STATE_ON_INIT;

        Intent intent = new Intent(mAppContext, DialogActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mAppContext.startActivity(intent);
    }

    /**
     * NOTE: pls use it carefully !!! and pls remember to call this method again at another time to invoke dialog-queue !!!
     *
     * @param interrupt stop showing rest dialog for now or not
     */
    public synchronized void setInterruptState(boolean interrupt) {
        mIsInterrupted = interrupt;
        tryShowDialog();
    }

    public synchronized void clearDialogContainer(@NonNull DialogActivity source) {
        boolean validClear = true;
        if (mCurDialogContainer != null) {
            DialogActivity container = mCurDialogContainer.get();
            if (container != null) {
                if (!container.equals(source)) {
                    validClear = false;
                }
            }
        }
        if (validClear) {
            mCurDialogContainer = null;
            mCurContainerState = CUR_CONTAINER_STATE_INVALID;
        }
    }

    public synchronized void setCurDialogContainer(DialogActivity container) {
        mCurDialogContainer = new WeakReference<>(container);
        mCurContainerState = CUR_CONTAINER_STATE_AVAILABLE;

        tryShowDialog();
    }

    public synchronized void clear() {
        if (!mDialogFragmentsQueue.isEmpty()) {
            mDialogFragmentsQueue.clear();
        }
        mCurDialogContainer = null;
        mCurContainerState = CUR_CONTAINER_STATE_INVALID;
        mIsInterrupted = false;
    }
}

3. dialig的几个接口类

package com.example.commonlib.dialog;

/**
 * Created by malei on 2019-12-06
 * Describe:当前和新的弹出框进行比较,根据级别处理两者之间的关系
 */
public class DialogUtil {

    public static int compareDialogPriority(BaseDialogFragment curDialog, BaseDialogFragment newDialog) {

        int result = PriorityCompareResult.INVALID_COMPARE;

        if (newDialog != null && curDialog != null) {

            int curPriority = curDialog.getPriorityLevel();
            int newPriority = newDialog.getPriorityLevel();

            if (curPriority == DialogPriority.LEVEL_0) {
                // 清空现有弹窗栈,并展示新弹窗
                result = PriorityCompareResult.SHOW_NEW_DIALOG_AND_CLEAR_ALREADY_SHOWN;

            } else if (newPriority < curPriority) {
                //如果新弹窗的级别小于当前弹窗,就展示新弹窗
                result = PriorityCompareResult.SHOW_NEW_DIALOG;

            } else {
                //如果新弹窗的级别大于当前弹窗,新弹窗不会展示,还是会展示当前弹窗
                result = PriorityCompareResult.HOLD_CUR_DIALOG;

            }

        } else if (newDialog != null) { // 展示新弹窗 只有新弹窗

            result = PriorityCompareResult.SHOW_NEW_DIALOG;

        } else if (curDialog != null) { // 维持当前弹窗状态不变 只有当前弹窗

            result = PriorityCompareResult.HOLD_CUR_DIALOG;
        }
        return result;
    }

}
/**
 * Created by malei on 2019-12-06
 * Describe:自定义dialog选用,需额外回调时使用,否则仅override同名abstract方法即可
 */
public interface IDialogCallback {

    void onShow();
    void onConfirm();
    void onClose();
    void onBackPressed();
    void onDismiss();
}
/**
 * Created by malei on 2019-12-06
 * Describe:自定义dialog请勿使用
 */
public interface IInnerDialogCallback {
    void onDismiss(boolean showNextDialog);
}
/**
 * Created by malei on 2019-12-06
 * Describe:
 */
public interface PriorityCompareResult {

    int INVALID_COMPARE = -1;
    int SHOW_NEW_DIALOG_AND_CLEAR_ALREADY_SHOWN = 0;  // 只有新创建的弹窗设置为DialogPriority.LEVEL_0时,会清空所有旧的弹框,只展示新的弹窗
    int SHOW_NEW_DIALOG = 1;   // 有旧的弹窗,又创建新弹窗,展示新弹窗
    int HOLD_CUR_DIALOG = 2;   // 没有新弹窗,只有旧的弹窗没有销毁

}
/**
 * Created by malei on 2019-12-06
 * Describe:
 */
/**
 *
 * 弹窗优先级规则:
 *
 * 1)LEVEL_0的弹窗会关闭掉所有其他弹窗(包含已弹出但未关闭的其它LEVEL_0弹窗),并弹出自身
 * 2)除LEVEL_0外,其余等级弹窗弹出时均不会关闭当前已弹出的弹窗
 * 3)除LEVEL_0外,已弹出未关闭的弹窗不能被等于或小于其优先级的弹窗覆盖
 */
public class DialogPriority {

    /**
     * 默认优先级,普通弹窗(如规则说明弹窗、未明确要求优先级的弹窗等)使用
     */
    public static final int LEVEL_DEFAULT = Integer.MAX_VALUE;

    /**
     * 谨慎使用!
     *
     * 立即弹出,并关闭目前已弹出的所有弹窗
     */
    public static final int LEVEL_0 = 0;

    /**
     * 目前涵盖:热启动闪屏
     */
    public static final int LEVEL_1000 = 1000;
    
}

4.创建一个Activity的中转类

package com.example.commonlib.dialog;

import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.View;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import java.lang.ref.WeakReference;
import java.util.Stack;

/**
 * Created by malei on 2019-12-06
 * Describe:
 */
public class DialogActivity extends AppCompatActivity {

    private static final String TAG = DialogActivity.class.getSimpleName();
    private Stack<WeakReference<BaseDialogFragment>> mDialogBeanStack = new Stack<>(); // 已弹出的弹窗栈
    private BaseDialogFragment mCurDialog;
    private volatile boolean mIsActive;

    private IInnerDialogCallback mCurInnerCallback = new IInnerDialogCallback() {
        @Override
        public void onDismiss(boolean showNextDialog) {
            if (showNextDialog) {
                closeCurDialog(false); // 重置当前弹窗状态
                fetchAndShowTopDialogBean();
            }
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(new View(this));

    }

    private void fetchAndShowTopDialogBean() {
        if (DialogManager.INSTANCE.isNonValidDialog() && mDialogBeanStack.isEmpty()) {
            finish();
        } else {
            BaseDialogFragment queueDialog = DialogManager.INSTANCE.peekTopDialog();
            if (mCurDialog == null) {
                mCurDialog = getTopValidDialogFromStack();
            }

            int compareResult = DialogUtil.compareDialogPriority(mCurDialog, queueDialog);
            switch (compareResult) {
                case PriorityCompareResult.SHOW_NEW_DIALOG_AND_CLEAR_ALREADY_SHOWN:
                case PriorityCompareResult.SHOW_NEW_DIALOG:
                    DialogManager.INSTANCE.removeCertainDialog(queueDialog);

                    if (compareResult == PriorityCompareResult.SHOW_NEW_DIALOG_AND_CLEAR_ALREADY_SHOWN) {
                        closeCurDialog(false);
                        clearDialogStack();
                    }
                    queueDialog.setInnerDialogCallback(mCurInnerCallback);
                    mDialogBeanStack.push(new WeakReference<>(queueDialog));
                    mCurDialog = queueDialog;
                    showDialog();
                    break;
                case PriorityCompareResult.INVALID_COMPARE:
                    closeCurDialog(false); // 重置当前弹窗状态
                    fetchAndShowTopDialogBean();
                    break;
                case PriorityCompareResult.HOLD_CUR_DIALOG:
                default:
                    showDialog();
                    break;
            }
        }
    }

    private void showDialog() {
        try {
            if (mCurDialog == null || mCurDialog.isAdded() || mCurDialog.isRemoving() || mCurDialog.isVisible() || isFinishing()) {
                return;
            }
            mCurDialog.onDialogInit();
            mCurDialog.setInnerDialogCallback(mCurInnerCallback);
            mCurDialog.showAllowingStateLoss(getSupportFragmentManager(), null);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    private void closeCurDialog(boolean showNextDialog) {
        if (!mDialogBeanStack.isEmpty()) {
            mDialogBeanStack.pop();
        }
        clearCurDialogDisposable();
        if (mCurDialog != null) {
            mCurDialog.closeDialog(showNextDialog);
            mCurDialog = null;
        }
    }

    /**
     * 取出当前已弹出的弹窗栈顶未被释放掉的弹窗
     */
    private BaseDialogFragment getTopValidDialogFromStack() {
        if (mDialogBeanStack == null || mDialogBeanStack.isEmpty()) {
            return null;
        }
        WeakReference<BaseDialogFragment> stackDialogBean = mDialogBeanStack.peek();
        BaseDialogFragment dialog;
        if (stackDialogBean != null) {
            dialog = stackDialogBean.get();
            if (dialog != null) {
                return dialog;
            }
        }

        mDialogBeanStack.pop();
        if (mDialogBeanStack.isEmpty()) {
            return null;
        } else {
            return getTopValidDialogFromStack();
        }
    }

    private void clearDialogStack() {
        if (mDialogBeanStack.isEmpty()) {
            return;
        }
        WeakReference<BaseDialogFragment> dialogBean = mDialogBeanStack.pop();
        if (dialogBean != null) {
            BaseDialogFragment dialog = dialogBean.get();
            if (dialog != null) {
                dialog.closeDialog(false);
            }
        }
        clearDialogStack();
    }

    private void clearCurDialogDisposable() {
        if (mCurDialog != null) {
            mCurDialog.clearDisposable();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        mIsActive = true;
        DialogManager.INSTANCE.setCurDialogContainer(this);
    }

    @Override
    protected void onPause() {
        mIsActive = false;
        if (mCurDialog != null) {
            if (mCurDialog.isClosing()) {
                mCurDialog.closeDialogImmediately();
            } else {
                mCurDialog.closeDialogForNow();
            }
        }
        super.onPause();
    }

    public void showNextDialog() {
        if (mIsActive) {
            fetchAndShowTopDialogBean();
        }
    }

    @Override
    protected void onDestroy() {
        DialogManager.INSTANCE.clearDialogContainer(this);
        closeCurDialog(false);
        clearDialogStack();
        mCurInnerCallback = null;
        super.onDestroy();
    }

    @Override
    public void finish() {
        DialogManager.INSTANCE.clearDialogContainer(this);
        super.finish();
        overridePendingTransition(0, 0);
    }
}

5.动画相关的资源文件

dialog_zoom_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/overshoot_interpolator"
    >
    <scale
        android:duration="300"
        android:fillAfter="false"
        android:fromXScale="0.0"
        android:fromYScale="0.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.0"
        android:toYScale="1.0"
        />
</set>

dialog_zoom_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/anticipate_interpolator"
    >
    <scale
        android:duration="200"
        android:fillAfter="true"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="0.0"
        android:toYScale="0.0"
        />

    <alpha
        android:duration="200"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
</set>

主题

 <style name="dialog_without_anim_style" parent="@android:style/Animation.Translucent">
        <item name="android:windowEnterAnimation">@null</item>
        <item name="android:windowExitAnimation">@null</item>
    </style>

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一个通用的Android端弹窗管理框架,内部维护弹窗优先级队列 具备弹窗管理扩展功能 整合Dialog,PoupoWindow,悬浮Widget,透明Webview,Toast,SnackBar,无需再为繁琐的业务弹窗逻辑所困扰如何添加依赖只需要两行代码轻松接入//add this to your repositories  maven { url 'https://www.jitpack.io' } //add this to your dependencies implementation 'com.github.MrCodeSniper:PopLayer:2.0.0'具体如何使用1.根据策略创建对应的弹窗view//Dialog形式 PopLayerView  mLayerView = new PopLayerView(this,R.layout.common_dialog_upgrade_app); //透明Webview形式 PopLayerView mLayerView = new PopLayerView(this,LayerConfig.redPocketScheme);2.开始装配弹窗配置Popi mUpgradePopi1 = new Popi.Builder()                 .setmPopId(4)//弹窗的唯一标识 当id发生改变 视为新的弹窗                 .setmPriority(2)//优先级这里不具体划分对应的范围 值越小优先级越高                 .setmCancelType(TRIGGER_CANCEL)//弹窗消失的类型分为 TRIGGER_CANCEL(触摸消失) COUNTDOWN_CANCEL (延时消失)                 .setMaxShowTimeLength(5)//最长显示时间(S)                 .setMaxShowCount(5)//最大显示次数                 .setmBeginDate(1548858028)//开始时间 2019-01-30 22:20:28                 .setmEndDate(1548944428)//结束时间 2019-01-31 22:20:28                 .setLayerView(mLayerView)//弹窗View                 .build();3.纳入弹窗管理//纳入弹窗管理 PopManager.getInstance().pushToQueue(mUpgradePopi); //开始显示弹窗 PopManager.getInstance().showNextPopi();效果预览未来的计划逐步统一 其他类型的弹窗 希望能提供给大家一个较为全面的应对业务需求的弹窗管理框架版本记录V1方案版本号LOG进度更新V1.0.0项目开源,完成弹窗管理Dialog形式扩展Dialog策略扩展完成V1.0.1修复Dialog策略无法获取dialog实体bugDialog策略优化V1.0.2修复activity摧毁造成的弹窗异常 bugDialog策略优化V1.0.3优化了弹窗的使用更加方便快捷框架使用优化V2方案版本号LOG进度更新V2.0.0正式加入透明Webview弹窗策略扩展透明Webview策略扩展完成作者介绍Hello 我叫lalala,如果您喜欢这个项目 请给个star 能follow我那真是太好了!!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值