package com.android.app_base.base.dialog; import static com.blankj.utilcode.util.StringUtils.getString; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Application; import android.content.Context; import android.content.DialogInterface; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; import android.util.SparseArray; 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.inputmethod.InputMethodManager; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.ColorInt; import androidx.annotation.DrawableRes; import androidx.annotation.FloatRange; import androidx.annotation.IdRes; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.StyleRes; import androidx.appcompat.app.AppCompatDialog; import androidx.core.content.ContextCompat; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleRegistry; import com.android.app_base.R; import com.android.app_base.base.BaseApplication; import com.android.app_base.base.action.ActivityAction; import com.android.app_base.base.action.AnimAction; import com.android.app_base.base.action.ClickAction; import com.android.app_base.base.action.HandlerAction; import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.List; /** * 基类dialog */ public class BaseDialog extends AppCompatDialog implements LifecycleOwner, ActivityAction, AnimAction, HandlerAction, ClickAction,DialogInterface.OnShowListener, DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { private final ListenersWrapper mListeners = new ListenersWrapper<>(this); private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this); private List mShowListeners; private List mCancelListeners; private List mDismissListeners; public BaseDialog(Context context) { this(context, R.style.BaseDialogStyle); } public BaseDialog(Context context, @StyleRes int themeResId) { super(context, themeResId); } /** * 获取 Dialog 的根布局 */ public View getContentView() { return findViewById(Window.ID_ANDROID_CONTENT); } /** * 获取当前设置重心 */ public int getGravity() { Window window = getWindow(); if (window != null) { WindowManager.LayoutParams params = window.getAttributes(); return params.gravity; } return Gravity.NO_GRAVITY; } /** * 设置宽度 */ public void setWidth(int width) { Window window = getWindow(); if (window != null) { WindowManager.LayoutParams params = window.getAttributes(); params.width = width; window.setAttributes(params); } } /** * 设置高度 */ public void setHeight(int height) { Window window = getWindow(); if (window != null) { WindowManager.LayoutParams params = window.getAttributes(); params.height = height; window.setAttributes(params); } } /** * 设置 Dialog 重心 */ public void setGravity(int gravity) { Window window = getWindow(); if (window != null) { window.setGravity(gravity); } } /** * 设置 Dialog 的动画 */ public void setWindowAnimations(@StyleRes int id) { Window window = getWindow(); if (window != null) { window.setWindowAnimations(id); } } /** * 获取 Dialog 的动画 */ public int getWindowAnimations() { Window window = getWindow(); if (window != null) { return window.getAttributes().windowAnimations; } return BaseDialog.ANIM_DEFAULT; } /** * 设置背景遮盖层开关 */ public void setBackgroundDimEnabled(boolean enabled) { Window window = getWindow(); if (window != null) { if (enabled) { window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); } else { window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); } } } /** * 设置背景遮盖层的透明度(前提条件是背景遮盖层开关必须是为开启状态) */ public void setBackgroundDimAmount(@FloatRange(from = 0.0, to = 1.0) float dimAmount) { Window window = getWindow(); if (window != null) { window.setDimAmount(dimAmount); } } @Override public void dismiss() { removeCallbacks(); View focusView = getCurrentFocus(); if (focusView != null) { BaseApplication.getInstance().getSystemService(InputMethodManager.class).hideSoftInputFromWindow(focusView.getWindowToken(), 0); } super.dismiss(); } /** * 设置一个显示监听器 * * @param listener 显示监听器对象 * @deprecated 请使用 {@link #addOnShowListener(OnShowListener)}} */ @Deprecated @Override public void setOnShowListener(@Nullable DialogInterface.OnShowListener listener) { if (listener == null) { return; } addOnShowListener(new ShowListenerWrapper(listener)); } /** * 设置一个取消监听器 * * @param listener 取消监听器对象 * @deprecated 请使用 {@link #addOnCancelListener(OnCancelListener)} */ @Deprecated @Override public void setOnCancelListener(@Nullable DialogInterface.OnCancelListener listener) { if (listener == null) { return; } addOnCancelListener(new CancelListenerWrapper(listener)); } /** * 设置一个销毁监听器 * * @param listener 销毁监听器对象 * @deprecated 请使用 {@link #addOnDismissListener(OnDismissListener)} */ @Deprecated @Override public void setOnDismissListener(@Nullable DialogInterface.OnDismissListener listener) { if (listener == null) { return; } addOnDismissListener(new DismissListenerWrapper(listener)); } /** * 设置一个按键监听器 * * @param listener 按键监听器对象 * @deprecated 请使用 {@link #setOnKeyListener(OnKeyListener)} */ @Deprecated @Override public void setOnKeyListener(@Nullable DialogInterface.OnKeyListener listener) { super.setOnKeyListener(listener); } public void setOnKeyListener(@Nullable OnKeyListener listener) { super.setOnKeyListener(new KeyListenerWrapper(listener)); } /** * 添加一个显示监听器 * * @param listener 监听器对象 */ public void addOnShowListener(@Nullable OnShowListener listener) { if (mShowListeners == null) { mShowListeners = new ArrayList<>(); super.setOnShowListener(mListeners); } mShowListeners.add(listener); } /** * 添加一个取消监听器 * * @param listener 监听器对象 */ public void addOnCancelListener(@Nullable OnCancelListener listener) { if (mCancelListeners == null) { mCancelListeners = new ArrayList<>(); super.setOnCancelListener(mListeners); } mCancelListeners.add(listener); } /** * 添加一个销毁监听器 * * @param listener 监听器对象 */ public void addOnDismissListener(@Nullable OnDismissListener listener) { if (mDismissListeners == null) { mDismissListeners = new ArrayList<>(); super.setOnDismissListener(mListeners); } mDismissListeners.add(listener); } /** * 移除一个显示监听器 * * @param listener 监听器对象 */ public void removeOnShowListener(@Nullable OnShowListener listener) { if (mShowListeners != null) { mShowListeners.remove(listener); } } /** * 移除一个取消监听器 * * @param listener 监听器对象 */ public void removeOnCancelListener(@Nullable OnCancelListener listener) { if (mCancelListeners != null) { mCancelListeners.remove(listener); } } /** * 移除一个销毁监听器 * * @param listener 监听器对象 */ public void removeOnDismissListener(@Nullable OnDismissListener listener) { if (mDismissListeners != null) { mDismissListeners.remove(listener); } } /** * 设置显示监听器集合 */ private void setOnShowListeners(@Nullable List listeners) { super.setOnShowListener(mListeners); mShowListeners = listeners; } /** * 设置取消监听器集合 */ private void setOnCancelListeners(@Nullable List listeners) { super.setOnCancelListener(mListeners); mCancelListeners = listeners; } /** * 设置销毁监听器集合 */ private void setOnDismissListeners(@Nullable List listeners) { super.setOnDismissListener(mListeners); mDismissListeners = listeners; } /** * {@link DialogInterface.OnShowListener} */ @Override public void onShow(DialogInterface dialog) { mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME); if (mShowListeners != null) { for (int i = 0; i < mShowListeners.size(); i++) { mShowListeners.get(i).onShow(this); } } } /** * {@link DialogInterface.OnCancelListener} */ @Override public void onCancel(DialogInterface dialog) { if (mCancelListeners != null) { for (int i = 0; i < mCancelListeners.size(); i++) { mCancelListeners.get(i).onCancel(this); } } } /** * {@link DialogInterface.OnDismissListener} */ @Override public void onDismiss(DialogInterface dialog) { mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY); if (mDismissListeners != null) { for (int i = 0; i < mDismissListeners.size(); i++) { mDismissListeners.get(i).onDismiss(this); } } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); } @Override protected void onStart() { super.onStart(); mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START); } @Override protected void onStop() { super.onStop(); mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP); } @SuppressWarnings("unchecked") public static class Builder implements LifecycleOwner, ActivityAction,ClickAction{ /** 上下文对象 */ private final Context mContext; /** Dialog 对象 */ private BaseDialog mDialog; /** Dialog 布局 */ private View mContentView; /** 主题样式 */ private int mThemeId = R.style.BaseDialogStyle; /** 动画样式 */ private int mAnimStyle = BaseDialog.ANIM_DEFAULT; /** 重心位置 */ private int mGravity = Gravity.NO_GRAVITY; /** 水平偏移 */ private int mXOffset; /** 垂直偏移 */ private int mYOffset; /** 宽度和高度 */ private int mWidth = ViewGroup.LayoutParams.WRAP_CONTENT; private int mHeight = ViewGroup.LayoutParams.WRAP_CONTENT; /** 背景遮盖层开关 */ private boolean mBackgroundDimEnabled = true; /** 背景遮盖层透明度 */ private float mBackgroundDimAmount = 0.5f; /** 是否能够被取消 */ private boolean mCancelable = true; /** 点击空白是否能够取消 前提是这个对话框可以被取消 */ private boolean mCanceledOnTouchOutside = true; /** Dialog Show 监听 */ private List mOnShowListeners; /** Dialog Cancel 监听 */ private List mOnCancelListeners; /** Dialog Dismiss 监听 */ private List mOnDismissListeners; /** Dialog Key 监听 */ private OnKeyListener mOnKeyListener; /** 点击事件集合 */ private SparseArray mClickArray; public Builder(Activity activity) { this((Context) activity); } public Builder(Context context) { mContext = context; } /** * 设置主题 id */ public B setThemeStyle(@StyleRes int id) { if (isCreated()) { // Dialog 创建之后不能再设置主题 id throw new IllegalStateException("are you ok?"); } mThemeId = id; return (B) this; } /** * 设置布局 */ public B setContentView(@LayoutRes int id) { // 这里解释一下,为什么要传 new FrameLayout,因为如果不传的话,XML 的根布局获取到的 LayoutParams 对象会为空,也就会导致宽高参数解析不出来 return setContentView(LayoutInflater.from(mContext).inflate(id, new FrameLayout(mContext), false)); } public B setContentView(View view) { mContentView = view; if (isCreated()) { mDialog.setContentView(view); } else { if (mContentView != null) { ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); if (layoutParams != null && mWidth == ViewGroup.LayoutParams.WRAP_CONTENT && mHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { // 如果当前 Dialog 的宽高设置了自适应,就以布局中设置的宽高为主 setWidth(layoutParams.width); setHeight(layoutParams.height); } // 如果当前没有设置重心,就自动获取布局重心 if (mGravity == Gravity.NO_GRAVITY) { if (layoutParams instanceof FrameLayout.LayoutParams) { setGravity(((FrameLayout.LayoutParams) layoutParams).gravity); } else if (layoutParams instanceof LinearLayout.LayoutParams) { setGravity(((LinearLayout.LayoutParams) layoutParams).gravity); } else { // 默认重心是居中 setGravity(Gravity.CENTER); } } } } return (B) this; } /** * 设置重心位置 */ public B setGravity(int gravity) { // 适配 Android 4.2 新特性,布局反方向(开发者选项 - 强制使用从右到左的布局方向) mGravity = gravity; if (isCreated()) { mDialog.setGravity(gravity); } return (B) this; } /** * 设置水平偏移 */ public B setXOffset(int offset) { mXOffset = offset; return (B) this; } /** * 设置垂直偏移 */ public B setYOffset(int offset) { mYOffset = offset; return (B) this; } /** * 设置宽度 */ public B setWidth(int width) { mWidth = width; if (isCreated()) { mDialog.setWidth(width); } else { ViewGroup.LayoutParams params = mContentView != null ? mContentView.getLayoutParams() : null; if (params != null) { params.width = width; mContentView.setLayoutParams(params); } } return (B) this; } /** * 设置高度 */ public B setHeight(int height) { mHeight = height; if (isCreated()) { mDialog.setHeight(height); } else { // 这里解释一下为什么要重新设置 LayoutParams // 因为如果不这样设置的话,第一次显示的时候会按照 Dialog 宽高显示 // 但是 Layout 内容变更之后就不会按照之前的设置宽高来显示 // 所以这里我们需要对 View 的 LayoutParams 也进行设置 ViewGroup.LayoutParams params = mContentView != null ? mContentView.getLayoutParams() : null; if (params != null) { params.height = height; mContentView.setLayoutParams(params); } } return (B) this; } /** * 是否可以取消 */ public B setCancelable(boolean cancelable) { mCancelable = cancelable; if (isCreated()) { mDialog.setCancelable(cancelable); } return (B) this; } /** * 是否可以通过点击空白区域取消 */ public B setCanceledOnTouchOutside(boolean cancel) { mCanceledOnTouchOutside = cancel; if (isCreated() && mCancelable) { mDialog.setCanceledOnTouchOutside(cancel); } return (B) this; } /** * 设置动画,已经封装好几种样式,具体可见{@link AnimAction}类 */ public B setAnimStyle(@StyleRes int id) { mAnimStyle = id; if (isCreated()) { mDialog.setWindowAnimations(id); } return (B) this; } /** * 设置背景遮盖层开关 */ public B setBackgroundDimEnabled(boolean enabled) { mBackgroundDimEnabled = enabled; if (isCreated()) { mDialog.setBackgroundDimEnabled(enabled); } return (B) this; } /** * 设置背景遮盖层的透明度(前提条件是背景遮盖层开关必须是为开启状态) */ public B setBackgroundDimAmount(@FloatRange(from = 0.0, to = 1.0) float dimAmount) { mBackgroundDimAmount = dimAmount; if (isCreated()) { mDialog.setBackgroundDimAmount(dimAmount); } return (B) this; } /** * 添加显示监听 */ public B addOnShowListener(@NonNull OnShowListener listener) { if (isCreated()) { mDialog.addOnShowListener(listener); } else { if (mOnShowListeners == null) { mOnShowListeners = new ArrayList<>(); } mOnShowListeners.add(listener); } return (B) this; } /** * 添加取消监听 */ public B addOnCancelListener(@NonNull OnCancelListener listener) { if (isCreated()) { mDialog.addOnCancelListener(listener); } else { if (mOnCancelListeners == null) { mOnCancelListeners = new ArrayList<>(); } mOnCancelListeners.add(listener); } return (B) this; } /** * 添加销毁监听 */ public B addOnDismissListener(@NonNull OnDismissListener listener) { if (isCreated()) { mDialog.addOnDismissListener(listener); } else { if (mOnDismissListeners == null) { mOnDismissListeners = new ArrayList<>(); } mOnDismissListeners.add(listener); } return (B) this; } /** * 设置按键监听 */ public B setOnKeyListener(@NonNull OnKeyListener listener) { if (isCreated()) { mDialog.setOnKeyListener(listener); } else { mOnKeyListener = listener; } return (B) this; } /** * 设置文本 */ public B setText(@IdRes int viewId, @StringRes int stringId) { return setText(viewId, getString(stringId)); } public B setText(@IdRes int id, CharSequence text) { ((TextView) findViewById(id)).setText(text); return (B) this; } /** * 设置文本颜色 */ public B setTextColor(@IdRes int id, @ColorInt int color) { ((TextView) findViewById(id)).setTextColor(color); return (B) this; } /** * 设置提示 */ public B setHint(@IdRes int viewId, @StringRes int stringId) { return setHint(viewId, getString(stringId)); } public B setHint(@IdRes int id, CharSequence text) { ((TextView) findViewById(id)).setHint(text); return (B) this; } /** * 设置可见状态 */ public B setVisibility(@IdRes int id, int visibility) { findViewById(id).setVisibility(visibility); return (B) this; } /** * 设置背景 */ public B setBackground(@IdRes int viewId, @DrawableRes int drawableId) { return setBackground(viewId, ContextCompat.getDrawable(mContext, drawableId)); } public B setBackground(@IdRes int id, Drawable drawable) { findViewById(id).setBackground(drawable); return (B) this; } /** * 设置图片 */ public B setImageDrawable(@IdRes int viewId, @DrawableRes int drawableId) { return setBackground(viewId, ContextCompat.getDrawable(mContext, drawableId)); } public B setImageDrawable(@IdRes int id, Drawable drawable) { ((ImageView) findViewById(id)).setImageDrawable(drawable); return (B) this; } /** * 设置点击事件 */ public B setOnClickListener(@IdRes int id, @NonNull OnClickListener listener) { if (isCreated()) { View view = mDialog.findViewById(id); if (view != null) { view.setOnClickListener(new ViewClickWrapper(mDialog, listener)); } } else { if (mClickArray == null) { mClickArray = new SparseArray<>(); } mClickArray.put(id, listener); } return (B) this; } /** * 创建 */ @SuppressLint("RtlHardcoded") public BaseDialog create() { // 判断布局是否为空 if (mContentView == null) { throw new IllegalArgumentException("are you ok?"); } // 如果当前没有设置重心,就设置一个默认的重心 if (mGravity == Gravity.NO_GRAVITY) { mGravity = Gravity.CENTER; } // 如果当前没有设置动画效果,就设置一个默认的动画效果 if (mAnimStyle == BaseDialog.ANIM_DEFAULT) { switch (mGravity) { case Gravity.TOP: mAnimStyle = BaseDialog.ANIM_TOP; break; case Gravity.BOTTOM: mAnimStyle = BaseDialog.ANIM_BOTTOM; break; case Gravity.LEFT: mAnimStyle = BaseDialog.ANIM_LEFT; break; case Gravity.RIGHT: mAnimStyle = BaseDialog.ANIM_RIGHT; break; default: mAnimStyle = BaseDialog.ANIM_DEFAULT; break; } } mDialog = createDialog(mContext, mThemeId); mDialog.setContentView(mContentView); mDialog.setCancelable(mCancelable); if (mCancelable) { mDialog.setCanceledOnTouchOutside(mCanceledOnTouchOutside); } // 设置参数 Window window = mDialog.getWindow(); if (window != null) { WindowManager.LayoutParams params = window.getAttributes(); params.width = mWidth; params.height = mHeight; params.gravity = mGravity; params.x = mXOffset; params.y = mYOffset; params.windowAnimations = mAnimStyle; window.setAttributes(params); if (mBackgroundDimEnabled) { window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); window.setDimAmount(mBackgroundDimAmount); } else { window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); } } if (mOnShowListeners != null) { mDialog.setOnShowListeners(mOnShowListeners); } if (mOnCancelListeners != null) { mDialog.setOnCancelListeners(mOnCancelListeners); } if (mOnDismissListeners != null) { mDialog.setOnDismissListeners(mOnDismissListeners); } if (mOnKeyListener != null) { mDialog.setOnKeyListener(mOnKeyListener); } for (int i = 0; mClickArray != null && i < mClickArray.size(); i++) { mContentView.findViewById(mClickArray.keyAt(i)).setOnClickListener(new ViewClickWrapper(mDialog, mClickArray.valueAt(i))); } Activity activity = getActivity(); if (activity != null) { DialogLifecycle.with(activity, mDialog); } return mDialog; } /** * 显示 */ public BaseDialog show() { if (!isCreated()) { create(); } mDialog.show(); return mDialog; } /** * 销毁当前 Dialog */ public void dismiss() { if (mDialog != null) { mDialog.dismiss(); } } @Override public Context getContext() { return mContext; } /** * 当前 Dialog 是否创建了 */ public boolean isCreated() { return mDialog != null; } /** * 当前 Dialog 是否显示了 */ public boolean isShowing() { return mDialog != null && mDialog.isShowing(); } /** * 创建 Dialog 对象(子类可以重写此方法来改变 Dialog 类型) */ protected BaseDialog createDialog(Context context, @StyleRes int themeId) { return new BaseDialog(context, themeId); } /** * 延迟执行 */ public final void post(Runnable r) { if (isShowing()) { mDialog.post(r); } else { addOnShowListener(new ShowPostWrapper(r)); } } /** * 延迟一段时间执行 */ public final void postDelayed(Runnable r, long delayMillis) { if (isShowing()) { mDialog.postDelayed(r, delayMillis); } else { addOnShowListener(new ShowPostDelayedWrapper(r, delayMillis)); } } /** * 在指定的时间执行 */ public final void postAtTime(Runnable r, long uptimeMillis) { if (isShowing()) { mDialog.postAtTime(r, uptimeMillis); } else { addOnShowListener(new ShowPostAtTimeWrapper(r, uptimeMillis)); } } /** * 获取 Dialog 的根布局 */ public View getContentView() { return mContentView; } /** * 根据 id 查找 View */ @Override public V findViewById(@IdRes int id) { if (mContentView == null) { // 没有 setContentView 就想 findViewById ? throw new IllegalStateException("are you ok?"); } return mContentView.findViewById(id); } /** * 获取当前 Dialog 对象 */ @Nullable public BaseDialog getDialog() { return mDialog; } @Nullable @Override public Lifecycle getLifecycle() { if (mDialog != null) { return mDialog.getLifecycle(); } return null; } } /** * Dialog 生命周期管理 */ private static final class DialogLifecycle implements Application.ActivityLifecycleCallbacks, OnShowListener, OnDismissListener { private static void with(Activity activity, BaseDialog dialog) { new DialogLifecycle(activity, dialog); } private BaseDialog mDialog; private Activity mActivity; /** Dialog 动画样式(避免 Dialog 从后台返回到前台后再次触发动画效果) */ private int mDialogAnim; private DialogLifecycle(Activity activity, BaseDialog dialog) { mActivity = activity; dialog.addOnShowListener(this); dialog.addOnDismissListener(this); } @Override public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {} @Override public void onActivityStarted(@NonNull Activity activity) {} @Override public void onActivityResumed(@NonNull Activity activity) { if (mActivity != activity) { return; } if (mDialog != null && mDialog.isShowing()) { // 还原 Dialog 动画样式(这里必须要使用延迟设置,否则还是有一定几率会出现) mDialog.postDelayed(() -> { if (mDialog != null && mDialog.isShowing()) { mDialog.setWindowAnimations(mDialogAnim); } }, 100); } } @Override public void onActivityPaused(@NonNull Activity activity) { if (mActivity != activity) { return; } if (mDialog != null && mDialog.isShowing()) { // 获取 Dialog 动画样式 mDialogAnim = mDialog.getWindowAnimations(); // 设置 Dialog 无动画效果 mDialog.setWindowAnimations(BaseDialog.ANIM_EMPTY); } } @Override public void onActivityStopped(@NonNull Activity activity) {} @Override public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {} @Override public void onActivityDestroyed(@NonNull Activity activity) { if (mActivity != activity) { return; } if (mDialog != null) { mDialog.removeOnShowListener(this); mDialog.removeOnDismissListener(this); if (mDialog.isShowing()) { mDialog.dismiss(); } mDialog = null; } unregisterActivityLifecycleCallbacks(); // 释放 Activity 对象 mActivity = null; } @Override public void onShow(BaseDialog dialog) { mDialog = dialog; registerActivityLifecycleCallbacks(); } @Override public void onDismiss(BaseDialog dialog) { mDialog = null; unregisterActivityLifecycleCallbacks(); } /** * 注册 Activity 生命周期监听 */ private void registerActivityLifecycleCallbacks() { if (mActivity == null) { return; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { mActivity.registerActivityLifecycleCallbacks(this); } else { mActivity.getApplication().registerActivityLifecycleCallbacks(this); } } /** * 反注册 Activity 生命周期监听 */ private void unregisterActivityLifecycleCallbacks() { if (mActivity == null) { return; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { mActivity.unregisterActivityLifecycleCallbacks(this); } else { mActivity.getApplication().unregisterActivityLifecycleCallbacks(this); } } } /** * Dialog 监听包装类(修复原生 Dialog 监听器对象导致的内存泄漏) */ private static final class ListenersWrapper extends SoftReference implements DialogInterface.OnShowListener, DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { private ListenersWrapper(T referent) { super(referent); } @Override public void onShow(DialogInterface dialog) { if (get() != null) { get().onShow(dialog); } } @Override public void onCancel(DialogInterface dialog) { if (get() != null) { get().onCancel(dialog); } } @Override public void onDismiss(DialogInterface dialog) { if (get() != null) { get().onDismiss(dialog); } } } /** * 点击事件包装类 */ private static final class ViewClickWrapper implements View.OnClickListener { private final BaseDialog mDialog; private final OnClickListener mListener; private ViewClickWrapper(BaseDialog dialog, OnClickListener listener) { mDialog = dialog; mListener = listener; } @SuppressWarnings("unchecked") @Override public final void onClick(View v) { mListener.onClick(mDialog, v); } } /** * 显示监听包装类 */ private static final class ShowListenerWrapper extends SoftReference implements OnShowListener { private ShowListenerWrapper(DialogInterface.OnShowListener referent) { super(referent); } @Override public void onShow(BaseDialog dialog) { // 在横竖屏切换后监听对象会为空 if (get() != null) { get().onShow(dialog); } } } /** * 取消监听包装类 */ private static final class CancelListenerWrapper extends SoftReference implements OnCancelListener { private CancelListenerWrapper(DialogInterface.OnCancelListener referent) { super(referent); } @Override public void onCancel(BaseDialog dialog) { // 在横竖屏切换后监听对象会为空 if (get() != null) { get().onCancel(dialog); } } } /** * 销毁监听包装类 */ private static final class DismissListenerWrapper extends SoftReference implements OnDismissListener { private DismissListenerWrapper(DialogInterface.OnDismissListener referent) { super(referent); } @Override public void onDismiss(BaseDialog dialog) { // 在横竖屏切换后监听对象会为空 if (get() != null) { get().onDismiss(dialog); } } } /** * 按键监听包装类 */ private static final class KeyListenerWrapper implements DialogInterface.OnKeyListener { private final OnKeyListener mListener; private KeyListenerWrapper(OnKeyListener listener) { mListener = listener; } @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { // 在横竖屏切换后监听对象会为空 if (mListener != null && dialog instanceof BaseDialog) { mListener.onKey((BaseDialog) dialog, event); } return false; } } /** * post 任务包装类 */ private static final class ShowPostWrapper implements OnShowListener { private final Runnable mRunnable; private ShowPostWrapper(Runnable r) { mRunnable = r; } @Override public void onShow(BaseDialog dialog) { if (mRunnable != null) { dialog.removeOnShowListener(this); dialog.post(mRunnable); } } } /** * postDelayed 任务包装类 */ private static final class ShowPostDelayedWrapper implements OnShowListener { private final Runnable mRunnable; private final long mDelayMillis; private ShowPostDelayedWrapper(Runnable r, long delayMillis) { mRunnable = r; mDelayMillis = delayMillis; } @Override public void onShow(BaseDialog dialog) { if (mRunnable != null) { dialog.removeOnShowListener(this); dialog.postDelayed(mRunnable, mDelayMillis); } } } /** * postAtTime 任务包装类 */ private static final class ShowPostAtTimeWrapper implements OnShowListener { private final Runnable mRunnable; private final long mUptimeMillis; private ShowPostAtTimeWrapper(Runnable r, long uptimeMillis) { mRunnable = r; mUptimeMillis = uptimeMillis; } @Override public void onShow(BaseDialog dialog) { if (mRunnable != null) { dialog.removeOnShowListener(this); dialog.postAtTime(mRunnable, mUptimeMillis); } } } /** * 点击监听器 */ public interface OnClickListener { void onClick(BaseDialog dialog, V view); } /** * 显示监听器 */ public interface OnShowListener { /** * Dialog 显示了 */ void onShow(BaseDialog dialog); } /** * 取消监听器 */ public interface OnCancelListener { /** * Dialog 取消了 */ void onCancel(BaseDialog dialog); } /** * 销毁监听器 */ public interface OnDismissListener { /** * Dialog 销毁了 */ void onDismiss(BaseDialog dialog); } /** * 按键监听器 */ public interface OnKeyListener { /** * 触发了按键 */ boolean onKey(BaseDialog dialog, KeyEvent event); } }