package com.dftc.toastlibrary.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import com.dftc.toastlibrary.R;
import com.dftc.toastlibrary.others.ThreadManager;
import static com.dftc.toastlibrary.Dialog.DialogConstants.CUSTOM_DIALOG;
import static com.dftc.toastlibrary.Dialog.DialogConstants.DOUBLE_BTN_DIALOG;
import static com.dftc.toastlibrary.Dialog.DialogConstants.SINGLE_BTN_DIALOG;
import java.util.ArrayList;
import java.util.List;
public class DFDialog implements DialogInterface {
private static final String TAG = "DFDialog";
private RelativeLayout mTitleLayout;
private ImageView closeIv;
private Button btnLeft;
private Button btnRight;
private Button btnOne;
private ScrollView textMessageScrollView;
private TextView textTitle,textMessage;
private LinearLayout btnLayout;
private String mTextLeftBtn = "确定";
private String mTextRightBtn = "取消";
private String mTextSingleBtn = "我知道了";
private String mTitle = "标题";
private String mMessage = "锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦";
private boolean isTitleVisible = true;
private boolean isCloseBtnVisible = true;
private boolean isBtnLayoutVisible = true;
private boolean isSingle = false;
private int messageWidth = 800;
private int messageHeight = 960;
private boolean isMaxHeightDialog;
private String mWindowTitle = "DFBaseDialog";
public boolean isDialogShowing;
private final DFWindow mWindow;
protected Context mContext;
private WindowManager mWindowManager;
private final WindowManager.LayoutParams mLp;
private int type = DFWindowManager.DF_TYPE_APPLICATION_OVERLAY;
private boolean isShow;
//文本是否居中对齐
private boolean messageCenter;
//弹窗是否在分屏侧居中
private boolean isDialogInSplitScreen = true;
//是否为覆盖全屏(隐藏dock和状态栏)的弹窗
private boolean isDialogWithoutDockAndStatus;
//弹窗是否居中,默认为true(居中)
private boolean isCenterInScreen = true;
private int mXOffset;
private int mYOffset;
private View mRootView;
private View mStandardLayout;
private RelativeLayout mDialogLayout;
private DFDecorView mDecorView;
private View mContentView;
private View mCustomView;
private FrameLayout container;
private Bundle savedInstanceState;
private int mDialogType = DOUBLE_BTN_DIALOG;
private final Handler mMainHandler = new Handler(Looper.getMainLooper());
// 点击弹窗外部蒙层,弹窗是否消失,默认true会消失
private boolean isCanceledOnTouchOutside = true;
// 手势返回,弹窗是否消失,默认true会消失
private boolean isCanceledKeyBack = true;
//弹窗是否会被后来者弹窗打断
private boolean isDialogInterrupt;
private static int windowCount = 0;
private static List<DFWindow> activeWindows = new ArrayList<>();
// 新增:蒙层宽高自适应标志
private boolean isMaskAdaptive = false;
//默认弹窗设置:居中,有蒙层
public DFDialog(Context context) {
mContext = context;
mWindow = new DFWindow(context);
mDecorView = mWindow.getDecorView();
mWindowManager = mWindow.getWindowManager();
Log.i(TAG, "DFBaseDialog: type = " + type);
mLp = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getMaskHeight(),
type,
WindowManager.LayoutParams.FLAG_DIM_BEHIND
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSPARENT);
mDecorView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mLp.gravity = Gravity.CENTER;
mLp.dimAmount = 0.6f;
mLp.windowAnimations = R.style.DFDialogAnim;
mWindow.setAttributes(mLp);
mWindow.setFocusChangeListener(DFDialog.this::onWindowFocusChanged);
mDecorView.setKeyEventListener(event -> {
Log.d(TAG, "dispatchKeyEvent: ");
return DFDialog.this.dispatchKeyEvent(event);
});
mDecorView.setTouchEventListener(ev -> {
Log.d(TAG, "dispatchTouchEvent: ");
return DFDialog.this.dispatchTouchEvent(ev);
});
}
/**
* 设置蒙层宽高自适应(充满屏幕)
* @return Dialog实例
*/
public DFDialog setMaskAdaptive() {
isMaskAdaptive = true;
updateMaskSize();
// 监听布局变化
if (mWindow != null && mWindow.getDecorView() != null) {
mWindow.getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (isMaskAdaptive) {
updateMaskSize();
}
}
}
);
}
return this;
}
/**
* 更新蒙层尺寸
*/
private void updateMaskSize() {
if (isMaskAdaptive && mWindow != null) {
// 使用 WindowInsets 获取更精确的可见区域
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowInsets insets = mWindow.getDecorView().getRootWindowInsets();
Insets systemInsets = insets.getInsets(
WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout()
);
// 获取当前窗口的实际尺寸(适应分屏变化)
Display display = mContext.getDisplay();
Point size = new Point();
display.getRealSize(size);
int width = size.x - systemInsets.left - systemInsets.right;
int height = size.y - systemInsets.top - systemInsets.bottom;
mLp.width = width;
mLp.height = height;
mWindow.setAttributes(mLp);
} else {
// 兼容旧版本
Rect visibleRect = new Rect();
mWindow.getDecorView().getWindowVisibleDisplayFrame(visibleRect);
mLp.width = visibleRect.width();
mLp.height = visibleRect.height();
mWindow.setAttributes(mLp);
}
}
}
public DFDialog build(){
if(mDialogType == SINGLE_BTN_DIALOG){
buildSingleBtnDialog();
}else if(mDialogType == DOUBLE_BTN_DIALOG){
buildDoubleBtnDialog();
} else if(mDialogType == CUSTOM_DIALOG){
buildCustomDialog();
}
// else if(mDialogType == MESSAGE_DIALOG){
// buildMessageDialog();
// }
mDecorView.addView(mContentView);
mRootView = mContentView.findViewById(R.id.dialog_layout);
mStandardLayout = mContentView.findViewById(R.id.standard_layout);
mDialogLayout = mContentView.findViewById(R.id.df_dialog_layout);
// mDialogLayout.setOnTouchListener(new View.OnTouchListener() {
// @Override
// public boolean onTouch(View v, MotionEvent event) {
// Log.i(TAG, "mDialogLayout 触摸 onTouch: event = "+event);
// return false;
// }
// });
//触摸弹窗外部(标准弹窗类)
// mRootView.setOnTouchListener(new View.OnTouchListener() {
// @SuppressLint("ClickableViewAccessibility")
// @Override
// public boolean onTouch(View v, MotionEvent event) {
// Log.i(TAG, "mRootView 触摸 onTouch: event = "+event);
// return false;
// }
// });
//点击弹窗本身dismiss,无此需求,先注释掉
// mRootView.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// Log.i(TAG, "onClick: ");
// dismiss();
// }
// });
// 标准弹窗
if (mDialogType != CUSTOM_DIALOG) {
//标题区
mTitleLayout = mContentView.findViewById(R.id.title_layout);
closeIv = mContentView.findViewById(R.id.close_iv);
textTitle = mContentView.findViewById(R.id.dialog_title);
textTitle.setText(mTitle);
if(closeIv != null){
closeIv.setOnClickListener(v -> dismiss());
}
//文本区
textMessageScrollView = mContentView.findViewById(R.id.dialog_message_scrollview);
textMessage = mContentView.findViewById(R.id.dialog_message);
textMessage.setText(mMessage);
if(messageCenter) {
textMessage.setGravity(Gravity.CENTER);
textMessage.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
}
initData();
} else { //自定义弹窗
//覆盖为全屏的弹窗
if (isDialogWithoutDockAndStatus) {
container.getLayoutParams().width = (int) mContext.getResources().getDimension(R.dimen.full_screen_width);
container.getLayoutParams().height = (int) mContext.getResources().getDimension(R.dimen.full_screen_height);
}
}
//分屏(目前仅考虑应用在右侧2/3的场景)
if (getScreenWidthDp() != mContext.getResources().getDimension(R.dimen.full_screen_width) && isDialogInSplitScreen) {
Log.i(TAG, "分屏,弹窗在应用侧居中");
// setDialogPositionXOffset((int) mContext.getResources().getDimension(R.dimen.dialog_left_split_screen_800));
setDialogInSplitScreen();
}
//弹窗的偏移
if (!isCenterInScreen) {
setDialogPositionXYOffset(mXOffset,mYOffset);
}
show();
return this;
}
// 单按钮弹窗布局
private void buildSingleBtnDialog() {
mContentView = View.inflate(mContext, R.layout.dialog_single_btn, null);
btnOne = mContentView.findViewById(R.id.btn_one);
btnOne.setText(mTextSingleBtn);
btnOne.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onClickOneButtonListener != null) {
onClickOneButtonListener.onOneButtonClick();
}
}
});
}
// 双按钮弹窗布局
private void buildDoubleBtnDialog() {
mContentView = View.inflate(mContext, R.layout.dialog_double_btn, null);
btnLayout = mContentView.findViewById(R.id.two_btn_layout);
btnLeft = mContentView.findViewById(R.id.btn_left);
btnRight = mContentView.findViewById(R.id.btn_right);
btnLeft.setText(mTextLeftBtn);
btnRight.setText(mTextRightBtn);
btnLeft.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onClickTwoButtonListener != null) {
onClickTwoButtonListener.onLeftButtonClick();
}
}
});
btnRight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onClickTwoButtonListener != null) {
onClickTwoButtonListener.onRightButtonClick();
}
}
});
}
private void buildMessageDialog() {
mContentView = View.inflate(mContext, R.layout.dialog_message, null);
}
// 自定义按钮布局
private void buildCustomDialog() {
Log.i(TAG, "buildCustomDialog: ");
mContentView = View.inflate(mContext, R.layout.dialog_custom, null);
container = mContentView.findViewById(R.id.custom_layout);
container.addView(mCustomView);
}
// 标准布局灵活配置:
// 高度(最⼤⾼度960,超过则滑动显示),宽度(为800、960、1280三种宽度)
// 弹窗分类:有无标题区,有无×按钮,有无按钮区,是否超过最高高度
private void initData() {
// 弹窗宽高设置
setDialogWidth(messageWidth);
if (isMaxHeightDialog) {
setDialogHeight();
}
// 标题栏是否显示
if (isTitleVisible) {
textTitle.setText(mTitle);
} else {
mTitleLayout.setVisibility(View.GONE);
changePositionForTitleInVisible();
}
// 标题栏中关闭按钮是否显示
if (!isCloseBtnVisible) {
closeIv.setVisibility(View.GONE);
}
// 按钮区是否可见
if (!isBtnLayoutVisible) {
changePositionForBtnInVisible();
if (mDialogType == SINGLE_BTN_DIALOG) {
btnOne.setVisibility(View.GONE);
} else {
btnLayout.setVisibility(View.GONE);
}
}
}
//设置弹窗宽度
private void setDialogWidth(int width) {
Log.i(TAG, "setDialogWidth: width = "+width);
mDialogLayout.getLayoutParams().width = width;
}
//设置弹窗高度
public void setDialogHeight(int height) {
Log.i(TAG, "setDialogHeight: height = "+height);
mDialogLayout.getLayoutParams().height = height;
}
//设置弹窗最大高度
private void setDialogHeight() {
Log.i(TAG, "setDialogHeight: "+(mContext.getResources().getDimension(R.dimen.dialog_max_height)));
mDialogLayout.getLayoutParams().height = (int) mContext.getResources().getDimension(R.dimen.dialog_max_height);
}
// 提供刷新方法供 Activity 调用
public void refreshMaskSize() {
updateMaskSize();
}
//分屏状态时,弹窗在应用侧居中
private void setDialogInSplitScreen() {
// Rect bounds = new Rect();
// mDecorView.getWindowVisibleDisplayFrame(bounds);
// Log.i(TAG, "build: bounds.width() = "+bounds.width());
// 获取当前窗口的实际可见宽度(而非固定值)
DisplayMetrics metrics = new DisplayMetrics();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
mContext.getDisplay().getMetrics(metrics);
}
mLp.width = metrics.widthPixels; // 使用实际宽度
mLp.gravity = Gravity.END;
mWindow.setAttributes(mLp);
// mLp.width = 1280; // 使用实际可视区域宽度
// mLp.gravity = Gravity.END ; // 基于分屏区域对齐
// mWindow.setAttributes(mLp);
//
// mRootView.setBackgroundColor(mContext.getColor(R.color.dialog_mask_color));
// clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
// addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
}
//全屏状态时,弹窗居中
private void setDialogInFullScreen() {
mLp.width = ViewGroup.LayoutParams.MATCH_PARENT;
mLp.gravity = Gravity.CENTER;
mWindow.setAttributes(mLp);
clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
}
//设置弹窗横向和纵向位置的偏移
private void setDialogPositionXYOffset(int xOffset , int yOffset) {
Log.i(TAG, "setDialogPositionXYOffset: xOffset = "+xOffset + " yOffset = "+yOffset);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mDialogLayout.getLayoutParams();
params.removeRule(RelativeLayout.CENTER_IN_PARENT); //取消居中设置
params.topMargin = yOffset;
params.leftMargin = xOffset;
mDialogLayout.setLayoutParams(params);
if (mDialogType == CUSTOM_DIALOG) {
RelativeLayout.LayoutParams paramsCustom = (RelativeLayout.LayoutParams) container.getLayoutParams();
paramsCustom.removeRule(RelativeLayout.CENTER_HORIZONTAL); //取消横向居中设置
container.setLayoutParams(paramsCustom);
}
}
//设置弹窗横向位置的偏移
private void setDialogPositionXOffset(int xOffset) {
Log.i(TAG, "setDialogPositionXOffset: xOffset = "+xOffset );
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mDialogLayout.getLayoutParams();
params.removeRule(RelativeLayout.CENTER_IN_PARENT); //取消居中设置
params.addRule(RelativeLayout.CENTER_VERTICAL);
// 设置左边距100dp(需转换像素值)
params.leftMargin = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
mContext.getResources().getDimension(R.dimen.dialog_left_split_screen_800),
mContext.getResources().getDisplayMetrics()
);
mDialogLayout.setLayoutParams(params);
}
//标题栏不可见时,文本区距离上下的纵向位置与可见时不同
private void changePositionForTitleInVisible() {
float dpValueTextMessageTop = mContext.getResources().getDimension(R.dimen.dialog_textMessage_top_change);
float dpValueTextMessageBottom = mContext.getResources().getDimension(R.dimen.dialog_textMessage_bottom_change);
Log.i(TAG, "dpValueTextMessageTop: " + dpValueTextMessageTop);
Log.i(TAG, "changePositionForTitleInVisible: "+dpValueTextMessageBottom);
LinearLayout.LayoutParams paramMessage = (LinearLayout.LayoutParams) textMessageScrollView.getLayoutParams();
paramMessage.topMargin = (int)dpValueTextMessageTop;
paramMessage.bottomMargin = (int) dpValueTextMessageBottom;
textMessageScrollView.setLayoutParams(paramMessage);
// // 修改按钮位置(纵向)
// float dpValueBtn = mContext.getResources().getDimension(R.dimen.dialog_btn_top_change);
// Log.i(TAG, "dpValueBtn: " + dpValueBtn);
// if (mDialogType == SINGLE_BTN_DIALOG) {
// ViewGroup.MarginLayoutParams paramsBtnOne = (ViewGroup.MarginLayoutParams) btnOne.getLayoutParams();
// paramsBtnOne.topMargin = (int)dpValueBtn;
// btnLayout.setLayoutParams(paramsBtnOne);
// } else {
// LinearLayout.LayoutParams paramsBtn = (LinearLayout.LayoutParams) btnLayout.getLayoutParams();
// paramsBtn.topMargin = (int)dpValueBtn;
// btnLayout.setLayoutParams(paramsBtn);
// }
}
//按钮栏不可见时,文本的纵向位置与可见时不同(距离下面的位置)
private void changePositionForBtnInVisible() {
float dpValueTextMessage = mContext.getResources().getDimension(R.dimen.dialog_textMessage_bottom_change);
Log.i(TAG, "dpValueTextMessage: " + dpValueTextMessage);
LinearLayout.LayoutParams paramMessage = (LinearLayout.LayoutParams) textMessageScrollView.getLayoutParams();
paramMessage.bottomMargin = (int)dpValueTextMessage;
textMessageScrollView.setLayoutParams(paramMessage);
}
// 获取当前窗口宽度dp值
private int getScreenWidthDp() {
return mContext.getResources().getConfiguration().screenWidthDp;
}
// 获取当前窗口高度dp值
private int getScreenHeightDp() {
return mContext.getResources().getConfiguration().screenHeightDp;
}
// 获取蒙层的高度(与分辨率有关)
private int getMaskHeight() {
int maskHeight = (int) mContext.getResources().getDimension(R.dimen.dialog_mask_height);
Log.i(TAG, "getMaskHeight: maskHeight");
return maskHeight;
}
public <T extends View> T findViewById(@IdRes int id) {
return mDecorView.findViewById(id);
}
private void setFlags(int flags, int mask) {
final WindowManager.LayoutParams attrs = getAttributes();
attrs.flags = (attrs.flags & ~mask) | (flags & mask); //通过位操作更新 attrs.flags,仅修改掩码 mask 指定的标志位
//mForcedWindowFlags |= mask;
dispatchWindowAttributesChanged(attrs); //通知系统窗口属性已变更,触发重新布局或渲染
}
//添加flag
private void addFlags(int flags) {
setFlags(flags, flags);
}
//清除flag
private void clearFlags(int flags) {
setFlags(0, flags);
}
/**
* 默认是TOUCHABLE
*
* @param touchable 布尔值
* @return DFBaseDialog实例
*/
public DFDialog setTouchable(boolean touchable) {
if (!touchable) {
addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
} else {
clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
return this;
}
/**
* 默认是FOCUSABLE
*
* @param focusable 布尔值
* @return DFBaseDialog实例
*/
public DFDialog setFocusable(boolean focusable) {
if (!focusable) {
addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
} else {
clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
}
return this;
}
/**
* 默认是TOUCH_MODAL
*
* @param touchable 布尔值
* @return DFBaseDialog实例
*/
public DFDialog setOutsideTouchable(boolean touchable) {
if (touchable) {
addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
} else {
clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
}
return this;
}
/**
* 默认是不关心
*
* @param outsideable 布尔值
* @return DFBaseDialog实例
*/
public DFDialog setWatchOutsideable(boolean outsideable) {
if (outsideable) {
addFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
} else {
clearFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
}
return this;
}
private boolean isTouchPointInView(View view, int x, int y) {
if (view == null) {
return false;
}
int[] location = new int[2];
view.getLocationOnScreen(location);
int left = location[0];
int top = location[1];
int right = left + view.getMeasuredWidth();
int bottom = top + view.getMeasuredHeight();
if (y >= top && y <= bottom && x >= left
&& x <= right) {
return true;
}
return false;
}
/**
* 判断点击区域是否在弹窗外蒙层
*/
private boolean isClickOnBackground(int x, int y) {
Log.i(TAG, "isClickOnBackground: x = "+x);
Log.i(TAG, "isClickOnBackground: y = "+y);
int[] contentLocation = new int[2];
int width = messageWidth;
int height ;
if (mDialogType == CUSTOM_DIALOG) {
mCustomView.getLocationOnScreen(contentLocation);
height = mCustomView.getHeight();
width = mCustomView.getWidth();
} else {
mStandardLayout.getLocationOnScreen(contentLocation);
height = mStandardLayout.getHeight();
}
Log.i(TAG, "isClickOnBackground: width = "+width);
Log.i(TAG, "isClickOnBackground: height = "+height);
//弹窗上边缘y
int dialogTopY = contentLocation[1];
//弹窗下边缘y
int dialogBottomY = contentLocation[1] + height;
//弹窗左边缘x
int dialogLeftX = contentLocation[0];
//弹窗右边缘x
int dialogRightX = contentLocation[0] + width;
Log.i(TAG, "isClickOnBackground: dialogTopY = "+dialogTopY);
Log.i(TAG, "isClickOnBackground: dialogBottomY = "+dialogBottomY);
Log.i(TAG, "isClickOnBackground: dialogLeftX = "+dialogLeftX);
Log.i(TAG, "isClickOnBackground: dialogRightX = "+dialogRightX);
Rect rect = new Rect(dialogLeftX , dialogTopY , dialogRightX , dialogBottomY);
return !rect.contains(x,y);
}
public boolean dispatchKeyEvent(KeyEvent event) {
Log.d(TAG, "dispatchKeyEvent: event = "+event.toString());
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){
if (mKeyBackDialogDismissListener != null) {
mKeyBackDialogDismissListener.keyBackDialogDismiss();
}
if (isCanceledKeyBack) {
dismiss();
}
}
return true;
}
public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
Log.i(TAG, "dispatchTouchEvent: = " + ev);
Log.i(TAG, "dispatchTouchEvent: isCanceledOnTouchOutside = "+isCanceledOnTouchOutside);
if (isCanceledOnTouchOutside && ev.getAction() == MotionEvent.ACTION_UP) {
int x = (int) ev.getRawX();
int y = (int) ev.getRawY();
if (isClickOnBackground(x,y)) {
cancel();
if (mTouchMaskDialogDismissListener != null) {
mTouchMaskDialogDismissListener.touchMaskDialogDismiss();
}
return true;
}
}
return onTouchEvent(ev);
}
public boolean onTouchEvent(@NonNull MotionEvent event) {
return false;
}
/**
* 设置内容
* @param message 显示内容
* @return dialog实例
*/
public DFDialog setDialogMessage(String message) {
this.mMessage = message;
return this;
}
/**
* 设置内容
* @param resId 文言id
* @return dialog实例
*/
public DFDialog setDialogMessage(int resId) {
this.mMessage = mContext.getString(resId);
return this;
}
/**
* 设置弹窗是否有标题栏
* @param isVisible 是否有标题栏
* @return dialog实例
*/
public DFDialog setTitleLayout(boolean isVisible){
this.isTitleVisible = isVisible;
return this;
}
/**
* 设置弹窗标题栏是否有关闭按钮
* @param isVisible 是否有关闭按钮
* @return dialog实例
*/
public DFDialog setCloseBtn(boolean isVisible){
this.isCloseBtnVisible = isVisible;
return this;
}
/**
* 设置标题
* @param title 显示标题
* @return dialog实例
*/
public DFDialog setTextTitle(String title) {
this.mTitle = title;
return this;
}
/**
* 设置标题
* @param resId 标题id
* @return dialog实例
*/
public DFDialog setTextTitle(int resId) {
this.mTitle = mContext.getString(resId);
return this;
}
/**
* 设置弹窗是否有按钮栏
* @param isVisible 是否有按钮栏
* @return dialog实例
*/
public DFDialog setBtnLayout(boolean isVisible){
this.isBtnLayoutVisible = isVisible;
return this;
}
/**
* 设置左侧按钮文本
* @param leftText 显示左侧按钮文本
* @return dialog实例
*/
public DFDialog setLeftButtonText(String leftText) {
this.mTextLeftBtn = leftText;
mDialogType = DOUBLE_BTN_DIALOG;
return this;
}
/**
* 设置左侧按钮文本
* @param resId 文言id
* @return dialog实例
*/
public DFDialog setLeftButtonText(int resId) {
this.mTextLeftBtn = mContext.getString(resId);
mDialogType = DOUBLE_BTN_DIALOG;
return this;
}
/**
* 设置右侧按钮文本
* @param rightText 显示右侧按钮文本
* @return dialog实例
*/
public DFDialog setRightButtonText(String rightText) {
this.mTextRightBtn = rightText;
mDialogType = DOUBLE_BTN_DIALOG;
return this;
}
/**
* 设置右侧按钮文本
* @param resId 文言id
* @return dialog实例
*/
public DFDialog setRightButtonText(int resId) {
this.mTextRightBtn = mContext.getString(resId);
mDialogType = DOUBLE_BTN_DIALOG;
return this;
}
/**
* 设置单按钮文本
* @param textSingleBtn 显示单按钮文本
* @return dialog实例
*/
public DFDialog setSingleButtonText(String textSingleBtn) {
this.mTextSingleBtn = textSingleBtn;
mDialogType = SINGLE_BTN_DIALOG;
return this;
}
/**
* 设置单按钮文本
* @param resId 显示单按钮文本
* @return dialog实例
*/
public DFDialog setSingleButtonText(int resId) {
this.mTextSingleBtn = mContext.getString(resId);
mDialogType = SINGLE_BTN_DIALOG;
return this;
}
/**
* 设置是否为单按钮
* @param isSingle 是否是单按钮
* @return dialog实例
*/
public DFDialog setSingle(boolean isSingle) {
this.isSingle = isSingle;
if (isSingle) {
mDialogType = SINGLE_BTN_DIALOG;
} else {
mDialogType = DOUBLE_BTN_DIALOG;
}
return this;
}
/**
* 设置弹窗宽度
* @param width 弹窗宽度
* @return dialog实例
*/
public DFDialog setMessageWidth(int width) {
this.messageWidth = width;
return this;
}
/**
* 设置弹窗高度
* @param height 弹窗高度
* @return dialog实例
*/
public DFDialog setMessageHeight(int height) {
this.messageHeight = height;
return this;
}
/**
* 最大高度弹窗,文本显示不全,右侧滑块可上下滑动
* @return Dialog实例
*/
public DFDialog setMaxHeight(){
isMaxHeightDialog = true;
return this;
}
/**
* 设置全局自定义视图
* @param customView 全局自定义视图
* @return Dialog实例
*/
public DFDialog setCustomView(View customView ){
mCustomView = customView;
mDialogType = CUSTOM_DIALOG;
return this;
}
/**
* 设置message内容居中对齐
* @param center 显示内容是否居中显示
* @return Dialog实例
*/
public DFDialog setMessageCenter(boolean center) {
messageCenter = center;
return this;
}
/**
* 设置弹窗无蒙层
* @return Dialog实例
*/
public DFDialog setNoMask() {
clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
return this;
}
/**
* 设置弹窗偏移位置,在弹窗非居中态时调用
* @param XOffset 横向偏移,到左侧的距离
* @param YOffset 纵向偏移,到顶部的距离
* @return Dialog实例
*/
public DFDialog setDialogXYOffset(int XOffset , int YOffset) {
isCenterInScreen = false;
this.mXOffset = XOffset;
this.mYOffset = YOffset;
return this;
}
/**
* 设置为全屏弹窗,蒙层遮挡状态栏和dock栏
* @return Dialog实例
*/
public DFDialog setFullScreen() {
mLp.type = DFWindowManager.DF_TYPE_NAVIGATION_BAR_PANEL; //全屏弹窗暂定2024
mLp.height = ViewGroup.LayoutParams.MATCH_PARENT;
mWindow.setAttributes(mLp);
// isCanceledOnTouchOutside = false;
return this;
}
/**
* 设置弹窗层级
* @param dialogType 弹窗层级
* @return Dialog实例
*/
private DFDialog setDialogType(int dialogType) {
this.type = dialogType;
mLp.type = dialogType;
mWindow.setAttributes(mLp);
return this;
}
/**
* 设置弹窗类型
* @param dialogClass 弹窗类型
* @return Dialog实例
*/
public DFDialog setDialogClass(int dialogClass) {
switch (dialogClass){
case DialogConstants.DIALOG_TYPE_BASE:
Log.i(TAG, "setDialogClass: 默认层级 2038");
break;
case DialogConstants.DIALOG_TYPE_AIR:
Log.i(TAG, "setDialogClass: 空调层级弹窗 2041");
mLp.type = DFWindowManager.DF_TYPE_STATUS_BAR_ADDITIONAL;
mWindow.setAttributes(mLp);
break;
case DialogConstants.DIALOG_TYPE_NEGATION_SCREEN:
Log.i(TAG, "setDialogClass: 负一屏层级弹窗 2042");
mLp.type = DFWindowManager.DF_TYPE_DF_ALL_APP;
mWindow.setAttributes(mLp);
break;
case DialogConstants.DIALOG_TYPE_FLOAT:
Log.i(TAG, "setDialogClass: 浮动弹窗,根据实际场景设置层级");
mLp.type = DFWindowManager.DF_TYPE_DF_ALL_APP; //暂时设置为2042
mWindow.setAttributes(mLp);
break;
case DialogConstants.DIALOG_TYPE_FORCED_SCREEN:
Log.i(TAG, "setDialogClass: 霸屏场景弹窗 2043");
mLp.type = DFWindowManager.DF_TYPE_DF_VOICE;
mWindow.setAttributes(mLp);
break;
case DialogConstants.DIALOG_TYPE_TOAST:
Log.i(TAG, "setDialogClass: toast、语音、来电 2044");
mLp.type = DFWindowManager.DF_TYPE_DF_TOAST;
mWindow.setAttributes(mLp);
break;
case DFWindowManager.DF_TYPE_DISPLAY_OVERLAY:
Log.i(TAG, "setDialogClass: 金融授信 2026");
mLp.type = DFWindowManager.DF_TYPE_DISPLAY_OVERLAY;
mWindow.setAttributes(mLp);
break;
default:
break;
}
return this;
}
/**
* 同一层级,区分状态栏弹窗、普通弹窗、导航卡片弹窗
* @param feature 弹窗类型
* @return Dialog实例
*/
private DFDialog setWindowFeature(int feature) {
return this;
}
/**
* 设置弹窗是否会被后来者弹窗打断,默认会
* @param interrupt 是否会被后来者弹窗打断
* true : 弹窗A显示,打开弹窗B,A消失,B显示,关闭B后,AB都不显示
* false : 弹窗A显示,打开弹窗B,A暂时隐藏,B显示,关闭B后,A恢复显示状态
* @return Dialog实例
*/
private DFDialog setDialogNoInterrupt(boolean interrupt) {
this.isDialogInterrupt = interrupt;
return this;
}
/**
* 弹窗是否在分屏侧居中
* @param isCenterInSplitScreen false:分屏状态时,不在应用侧居中,而是全屏居中
* @return Dialog实例
*/
public DFDialog setDialogInSplitScreen (boolean isCenterInSplitScreen) {
this.isDialogInSplitScreen = isCenterInSplitScreen;
return this;
}
/**
* 设置为全屏窗口,隐藏dock栏和状态栏
* @return Dialog实例
*/
public DFDialog setFullScreenDialog() {
// addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
// addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
isDialogWithoutDockAndStatus = true;
mLp.height = WindowManager.LayoutParams.MATCH_PARENT;
// mLp.type = DFWindowManager.DF_TYPE_DF_ALL_APP;
mLp.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
mWindow.setAttributes(mLp);
return this;
}
/**
* 弹窗是否显示
* @return boolean值
*/
public boolean isShowing() {
return isShow;
}
/**
* 设置窗口标题名称
* @param title 标题
*/
public void setTitle(String title){
mWindowTitle = title;
}
/**
* 设置点击弹窗蒙层后弹窗不会dismiss
*/
public void setCanceledOnTouchOutside(){
this.isCanceledOnTouchOutside = false;
}
/**
* 屏蔽手势返回后弹窗消失的功能(手势返回后弹窗不消失)
*/
public void setKeyBackDialogNoDismiss() {
this.isCanceledKeyBack = false;
}
protected void findViews() {
}
protected void init(Bundle savedInstanceState) {
}
protected void setActions() {
}
protected void onStart() {
}
protected void onResume() {
}
protected void onStop() {
}
protected void onPause() {
}
public void onDialogShow() {
}
public void onDialogDismiss() {
}
protected void onDestroy() {
dismiss();
onDismissListener = null;
onShowListener = null;
}
public void onWindowFocusChanged(boolean hasFocus) {
Log.d(TAG, "onWindowFocusChanged: hasFocus = " + hasFocus);
Log.i(TAG, "onWindowFocusChanged: getScreenWidthDp = "+getScreenWidthDp());
// if (getScreenWidthDp() != mContext.getResources().getDimension(R.dimen.full_screen_width)) {
// setDialogInSplitScreen();
// } else {
// setDialogInFullScreen();
// }
}
Runnable showRunnable = new Runnable() {
@Override
public void run() {
try {
Log.i(TAG, "isShow = " + isShow + " hashcode = " + DFDialog.this.hashCode());
if (isShow) {
mWindowManager.removeViewImmediate(mDecorView);
}
onStart();
mWindow.setWindowAnimations(R.style.DFDialogAnim);
mWindowManager.addView(mDecorView, getAttributes());
Log.i(TAG, "realshow:" + getClass().getSimpleName() + " hashcode = " + DFDialog.this.hashCode());
onResume();
onDialogShow();
if (onShowListener != null) {
onShowListener.onShow(DFDialog.this);
}
isShow = true;
} catch (Exception e) {
Log.i(TAG, "e = " + e.getMessage());
}
}
};
/**
* 显示弹窗
*/
public void show() {
Log.i(TAG, "show: hashCode = " + DFDialog.this.hashCode());
mMainHandler.removeCallbacks(showRunnable);
if (ThreadManager.isMainThread()) {
showRunnable.run();
} else {
mMainHandler.post(showRunnable);
}
// 窗口管理
windowCount++;
activeWindows.add(mWindow);
logWindowInfo();
}
@Override
public void cancel() {
dismiss();
}
private Runnable dismissRun = new Runnable() {
@Override
public void run() {
try {
onPause();
if (!isShow) {
Log.d(TAG, "dismissRun: isShow==false; hashCode = " + DFDialog.this.hashCode());
return;
}
mWindowManager.removeViewImmediate(mDecorView);
Log.i(TAG, "run: realdismiss:" + getClass().getSimpleName() + " hashCode = " + DFDialog.this.hashCode());
onStop();
onDialogDismiss();
if (onDismissListener != null) {
onDismissListener.onDismiss(DFDialog.this);
}
isShow = false;
} catch (Exception e) {
Log.i(TAG, "run: " + e.getMessage());
e.printStackTrace();
}
}
};
/**
* 关闭弹窗
*/
@Override
public void dismiss() {
Log.i(TAG, "dismiss: hashCode = " + DFDialog.this.hashCode());
// if (!isShow) {
// return;
// }
mMainHandler.removeCallbacks(dismissRun);
if (ThreadManager.isMainThread()) {
dismissRun.run();
} else {
mMainHandler.post(dismissRun);
}
// 窗口管理
windowCount--;
activeWindows.remove(mWindow);
logWindowInfo();
}
private void logWindowInfo() {
WindowManager.LayoutParams params = (WindowManager.LayoutParams)
mWindow.getAttributes();
Log.i("WindowInfo",
"Type:" + params.type +
" X:" + params.x +
" Y:" + params.y +
" windowCount :" +windowCount);
}
public Context getContext() {
return mContext;
}
public View getDecorView() {
return mDecorView;
}
public View getCurrentFocus() {
if (mDecorView != null) {
return mDecorView.findFocus();
}
return null;
}
public Bundle getSavedInstanceState() {
return savedInstanceState;
}
public void setSavedInstanceState(Bundle savedInstanceState) {
this.savedInstanceState = savedInstanceState;
}
public final WindowManager.LayoutParams getAttributes() {
return mWindow.getAttributes();
}
/**
* {@hide}
*/
protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) {
}
private OnDismissListener onDismissListener;
private OnShowListener onShowListener;
public void setOnDismissListener(OnDismissListener listener) {
onDismissListener = listener;
}
public void setOnShowListener(OnShowListener listener) {
onShowListener = listener;
}
public interface OnShowListener {
void onShow(DFDialog window);
}
public TouchMaskDialogDismissListener mTouchMaskDialogDismissListener;
public KeyBackDialogDismissListener mKeyBackDialogDismissListener;
public OnClickTwoButtonListener onClickTwoButtonListener;
public OnClickOneButtonListener onClickOneButtonListener;
/**
* 设置蒙层监听
* @param touchMaskDialogDismissListener 点击监听器
*/
public void setDialogMaskListener(TouchMaskDialogDismissListener touchMaskDialogDismissListener){
this.mTouchMaskDialogDismissListener = touchMaskDialogDismissListener;;
}
/**
* 设置返回手势监听
* @param keyBackDialogDismissListener 点击监听器
*/
public void setKeyBackAction(KeyBackDialogDismissListener keyBackDialogDismissListener){
this.mKeyBackDialogDismissListener = keyBackDialogDismissListener;
}
/**
* 设置双按钮监听
* @param onClickTwoButtonListener 点击监听器
*/
public void setOnClickTwoButtonListener(OnClickTwoButtonListener onClickTwoButtonListener) {
this.onClickTwoButtonListener = onClickTwoButtonListener;
}
/**
* 设置单按钮监听
* @param onClickOneButtonListener 点击监听器
*/
public void setOnClickOneButtonListener(OnClickOneButtonListener onClickOneButtonListener) {
this.onClickOneButtonListener = onClickOneButtonListener;
}
/**点击蒙层监听*/
public interface TouchMaskDialogDismissListener{
/**
* 监听到手势回退的回调
*/
void touchMaskDialogDismiss();
}
/**返回手势监听*/
public interface KeyBackDialogDismissListener{
/**
* 监听到手势回退的回调
*/
void keyBackDialogDismiss();
}
/**双按钮点击监听*/
public interface OnClickTwoButtonListener{
/**
* 点击左侧确定按钮事件
*/
void onLeftButtonClick();
/**
* 点击右侧取消按钮事件
*/
void onRightButtonClick();
}
/**单按钮点击监听*/
public interface OnClickOneButtonListener{
/**
* 点击单按钮事件
*/
void onOneButtonClick();
}
}
优化有关蒙层的代码