new DispatchDialog.Builder(this)
.setContentView(you can set layout or view)
.setOutsideTouchable(false)
.setCancelable(false)
.setWindowModelRate(0.8F)
.setWindowAlpha(1.0F)
.setThemeResId(you can set theme)
.setAnimStyleResId(you can set anim)
.setWindowDimAmount(0.0F)
.setBackgroundResource(you can set drawable)
.setOnDismissListener(windowInterface -> {
do some thing
})
.setOnBackPressedListener(windowInterface -> {
do some thing
})
.setOnKeyListener((windowInterface, keyCode, event) -> {
return do some thing ;
})
.createDialog(action -> {
do some inject
})
.show(you can set gravity and Offset);
package com.virtual.leyi.alert;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.annotation.FloatRange;
import android.support.annotation.StyleRes;
import android.support.v4.content.ContextCompat;
import android.support.v4.util.SparseArrayCompat;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
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.widget.Checkable;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.RadioGroup;
import android.widget.TextView;
/**
* Copyright (C), 2015-2020, XXX有限公司
* FileName: DispatchDialog
* Author: Administrator
* Date: 2020/6/10 10:23
* Description: ${DESCRIPTION}
* History:
*/
public interface DispatchDialog {
interface Dialog {
void show();
void show(int gravity);
/**
* @param gravity
* @param x {@link Gravity#LEFT} 对话框出现在左边,所以layoutParams.x就表示相对左边的偏移
* {@link Gravity#RIGHT} 对话框出现在右边,所以params.x就表示相对右边的偏移
* @param y {@link Gravity#TOP} 对话框出现在上边,所以params.y就表示相对上边的偏移
* {@link Gravity#BOTTOM} 对话框出现在下边,所以params.y就表示相对下边的偏移
*/
void show(int gravity, int x, int y);
void dismiss();
}
interface OnBackPressedListener {
/**
* 点击返回键
*
* @param windowInterface
*/
void onBackPressed(WindowInterface windowInterface);
}
interface OnDismissListener {
void onDismiss(WindowInterface windowInterface);
}
interface OnKeyListener {
boolean onKey(WindowInterface windowInterface, int keyCode, KeyEvent event);
}
interface TextChangedListener {
void afterTextChanged(Editable s);
}
interface Action {
/**
* 自定义View
*
* @param target
*/
void apply(V target) throws Exception;
}
interface WindowInterface {
void dismiss();
V findViewById(int idResId);
V findContentView();
WindowInterface addView(int idResId, int layoutResId);
WindowInterface addView(int idResId, View subView);
WindowInterface tag(int idResId, Object object);
WindowInterface image(int idResId, int res);
WindowInterface visibility(int idResId, int visibility);
WindowInterface toggle(int idResId);
WindowInterface alpha(int idResId, float alpha);
WindowInterface text(int idResId, String text);
WindowInterface textGravity(int idResId, int gravity);
WindowInterface textColor(int idResId, int color);
WindowInterface typeface(int idResId, Typeface typeface, int style);
WindowInterface typeface(int idResId, Typeface typeface);
WindowInterface textSize(int idResId, int unit, float size);
WindowInterface textSize(int idResId, float size);
/**
* @param idResId
* @param flags {@link android.graphics.Paint#UNDERLINE_TEXT_FLAG} underline
* {@link android.graphics.Paint#ANTI_ALIAS_FLAG } 抗锯齿标志
* {@link android.graphics.Paint#FILTER_BITMAP_FLAG } 使位图过滤的位掩码标志
* {@link android.graphics.Paint#DITHER_FLAG } 使位图进行有利的抖动的位掩码标志
* {@link android.graphics.Paint#UNDERLINE_TEXT_FLAG } 下划线
* {@link android.graphics.Paint#STRIKE_THRU_TEXT_FLAG }中划线
* {@link android.graphics.Paint#FAKE_BOLD_TEXT_FLAG } 加粗
* {@link android.graphics.Paint#LINEAR_TEXT_FLAG } 使文本平滑线性扩展的油漆标志
* {@link android.graphics.Paint#SUBPIXEL_TEXT_FLAG } 使文本的亚像素定位的绘图标志
* {@link android.graphics.Paint#EMBEDDED_BITMAP_TEXT_FLAG } 绘制文本时允许使用位图字体的绘图标志
* @return
*/
WindowInterface textLine(int idResId, int flags);
WindowInterface textEditor(int idResId, TextView.OnEditorActionListener listener);
WindowInterface textChanged(int idResId, TextChangedListener listener);
WindowInterface checked(int idResId, boolean checked);
WindowInterface selected(int idResId, boolean selected);
WindowInterface clicked(int idResId, View.OnClickListener listener);
WindowInterface checkedCompoundChanged(int idResId, CompoundButton.OnCheckedChangeListener listener);
WindowInterface checkedRadioChanged(int idResId, RadioGroup.OnCheckedChangeListener listener);
WindowInterface focusChanged(int idResId, View.OnFocusChangeListener listener);
WindowInterface touch(int idResId, View.OnTouchListener listener);
}
class Builder {
private int windowModelWidth = ViewGroup.LayoutParams.WRAP_CONTENT,
windowModelHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
private Context mContext;
private View mContentView;
private boolean cancelable = true,
outsideTouchable = true;
private OnBackPressedListener onBackPressedListener;
private OnDismissListener onDismissListener;
private OnKeyListener onKeyListener;
private float windowAlpha = 1.0F;
private float windowDimAmount = 0.5F;
private Drawable mBackground;
private int themeResId, animStyleResId;
public Builder setBackgroundColor(@ColorInt int color) {
setBackground(new ColorDrawable(color));
return this;
}
public Builder setBackgroundResource(@DrawableRes int resid) {
setBackground(ContextCompat.getDrawable(mContext, resid));
return this;
}
public Builder setBackground(Drawable background) {
this.mBackground = background;
return this;
}
public Builder setThemeResId(@StyleRes int themeResId) {
if (themeResId == 0)
throw new IllegalArgumentException("u must input sure theme");
this.themeResId = themeResId;
return this;
}
public Builder setAnimStyleResId(@StyleRes int animStyleResId) {
if (animStyleResId == 0)
throw new IllegalArgumentException("u must input sure anim");
this.animStyleResId = animStyleResId;
return this;
}
public Builder setWindowDimAmount(@FloatRange(from = 0.0, to = 1.0) float windowDimAmount) {
if (windowDimAmount < 0 || windowDimAmount > 1)
throw new IllegalArgumentException("dimAmount value must range 0 to 1");
this.windowDimAmount = windowDimAmount;
return this;
}
public Builder setWindowAlpha(@FloatRange(from = 0.0, to = 1.0) float windowAlpha) {
if (windowAlpha < 0 || windowAlpha > 1)
throw new IllegalArgumentException("alpha value must range 0 to 1");
this.windowAlpha = windowAlpha;
return this;
}
public Builder setWindowModelRate(@FloatRange(from = 0.0, to = 1.0) float windowWidthRate) {
if (windowWidthRate < 0 || windowWidthRate > 1)
throw new IllegalArgumentException("alpha value must range 0 to 1");
Resources resources = this.mContext.getResources();
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
this.windowModelWidth = (int) (displayMetrics.widthPixels * windowWidthRate);
this.windowModelHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
return this;
}
public Builder setWindowModelSize(int windowModeWidth, int windowModeHeight) {
this.windowModelWidth = windowModeWidth;
this.windowModelHeight = windowModeHeight;
return this;
}
public Builder(Context context) {
this.mContext = context;
}
public Builder setContentView(int layoutResId) {
this.mContentView = LayoutInflater.from(mContext).inflate(layoutResId, null);
return this;
}
public Builder setContentView(View mContentView) {
this.mContentView = mContentView;
return this;
}
public Builder setCancelable(boolean cancelable) {
this.cancelable = cancelable;
return this;
}
public Builder setOutsideTouchable(boolean outsideTouchable) {
this.outsideTouchable = outsideTouchable;
return this;
}
public Builder setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
this.onBackPressedListener = onBackPressedListener;
return this;
}
public Builder setOnDismissListener(OnDismissListener onDismissListener) {
this.onDismissListener = onDismissListener;
return this;
}
public Builder setOnKeyListener(OnKeyListener onKeyListener) {
this.onKeyListener = onKeyListener;
return this;
}
public Dialog createDialog() {
return createDialog(null);
}
public Dialog createDialog(DispatchDialog.Action action) {
DialogImpl dialog = new DialogImpl(this);
if (action != null) {
try {
action.apply(dialog);
} catch (Exception e) {
Log.e("u inject action error", "please check the error : " + e.getMessage());
}
}
return dialog;
}
static class DialogImpl implements Dialog, DialogInterface.OnKeyListener, WindowInterface {
private SparseArrayCompat mViews;
AlertDialog mDialog;
Builder mBuilder;
DialogImpl(Builder mBuilder) {
this.mBuilder = mBuilder;
this.mViews = new SparseArrayCompat<>();
this.mDialog = new AlertDialog.Builder(mBuilder.mContext, mBuilder.themeResId)
.setView(mBuilder.mContentView)
.setCancelable(mBuilder.cancelable)
.create();
this.mBuilder.mContentView.setBackground(mBuilder.mBackground == null ? new ColorDrawable(Color.TRANSPARENT) : mBuilder.mBackground);
this.mDialog.setCanceledOnTouchOutside(mBuilder.outsideTouchable);
this.mDialog.setOnKeyListener(this);
}
@Override
public void show() {
this.show(Gravity.CENTER);
}
@Override
public void show(int gravity) {
this.show(gravity, 0, 0);
}
@Override
public void show(int gravity, int x, int y) {
this.mDialog.show();
Window window = this.mDialog.getWindow();
window.setGravity(gravity);
//设置dialog弹出时的动画效果,从屏幕底部向上弹出
if (this.mBuilder.animStyleResId != 0) {
window.setWindowAnimations(this.mBuilder.animStyleResId);
}
window.getDecorView()./*去掉dialog默认的padding*/setPadding(0, 0, 0, 0);
//获得window窗口的属性
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.width = mBuilder.windowModelWidth;
layoutParams.height = mBuilder.windowModelHeight;
layoutParams.x = x;
layoutParams.y = y;
//弹出层透明度
layoutParams.alpha = mBuilder.windowAlpha;
//背景改透明 window.setBackgroundDrawableResource(android.R.color.transparent);
//弹出层外部阴影
layoutParams.dimAmount = mBuilder.windowDimAmount;
//将设置好的属性set回去
window.setAttributes(layoutParams);
}
@Override
public void dismiss() {
if (null != mBuilder.onDismissListener) {
mBuilder.onDismissListener.onDismiss(this);
}
mDialog.dismiss();
}
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && null != mBuilder.onBackPressedListener) {
mBuilder.onBackPressedListener.onBackPressed(this);
}
if (null != mBuilder.onKeyListener) {
return mBuilder.onKeyListener.onKey(this, keyCode, event);
}
return false;
}
@Override
public V findViewById(int idResId) {
V view = (V) this.mViews.get(idResId);
if (view == null) {
view = this.mBuilder.mContentView.findViewById(idResId);
this.mViews.put(idResId, view);
}
return view;
}
@Override
public V findContentView() {
return (V) this.mBuilder.mContentView;
}
@Override
public WindowInterface addView(int idResId, int subLayoutResId) {
this.findViewById(idResId).addView(((LayoutInflater) mBuilder.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(subLayoutResId, null));
return this;
}
@Override
public WindowInterface addView(int idResId, View subView) {
this.findViewById(idResId).addView(subView);
return this;
}
@Override
public WindowInterface tag(int idResId, Object object) {
this.findViewById(idResId).setTag(object);
return this;
}
@Override
public WindowInterface image(int idResId, int res) {
this.findViewById(idResId).setImageResource(res);
return this;
}
@Override
public WindowInterface visibility(int idResId, int visibility) {
this.findViewById(idResId).setVisibility(visibility);
return this;
}
@Override
public WindowInterface toggle(int idResId) {
Checkable checkable = this.findViewById(idResId);
checkable.toggle();
return this;
}
@Override
public WindowInterface alpha(int idResId, float alpha) {
this.findViewById(idResId).setAlpha(alpha);
return this;
}
@Override
public WindowInterface text(int idResId, String text) {
this.findViewById(idResId).setText(text);
return this;
}
@Override
public WindowInterface textGravity(int idResId, int gravity) {
this.findViewById(idResId).setGravity(gravity);
return this;
}
@Override
public WindowInterface textColor(int idResId, int color) {
this.findViewById(idResId).setTextColor(color);
return this;
}
@Override
public WindowInterface typeface(int idResId, Typeface typeface, int style) {
this.findViewById(idResId).setTypeface(typeface, style);
return this;
}
@Override
public WindowInterface typeface(int idResId, Typeface typeface) {
this.findViewById(idResId).setTypeface(typeface);
return this;
}
@Override
public WindowInterface textSize(int idResId, int unit, float size) {
this.findViewById(idResId).setTextSize(unit, size);
return this;
}
@Override
public WindowInterface textSize(int idResId, float size) {
this.findViewById(idResId).setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
return this;
}
@Override
public WindowInterface textLine(int idResId, int flags) {
this.findViewById(idResId).getPaint().setFlags(flags);
return this;
}
@Override
public WindowInterface textEditor(int idResId, TextView.OnEditorActionListener listener) {
this.findViewById(idResId).setOnEditorActionListener(listener);
return this;
}
@Override
public WindowInterface textChanged(int idResId, TextChangedListener listener) {
this.findViewById(idResId).addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
listener.afterTextChanged(s);
}
});
return this;
}
@Override
public WindowInterface checked(int idResId, boolean checked) {
Checkable checkable = this.findViewById(idResId);
checkable.setChecked(checked);
return this;
}
@Override
public WindowInterface selected(int idResId, boolean selected) {
this.findViewById(idResId).setSelected(selected);
return this;
}
@Override
public WindowInterface clicked(int idResId, View.OnClickListener listener) {
this.findViewById(idResId).setOnClickListener(listener);
return this;
}
@Override
public WindowInterface checkedCompoundChanged(int idResId, CompoundButton.OnCheckedChangeListener listener) {
this.findViewById(idResId).setOnCheckedChangeListener(listener);
return this;
}
@Override
public WindowInterface checkedRadioChanged(int idResId, RadioGroup.OnCheckedChangeListener listener) {
this.findViewById(idResId).setOnCheckedChangeListener(listener);
return this;
}
@Override
public WindowInterface focusChanged(int idResId, View.OnFocusChangeListener listener) {
this.findViewById(idResId).setOnFocusChangeListener(listener);
return this;
}
@Override
public WindowInterface touch(int idResId, View.OnTouchListener listener) {
this.findViewById(idResId).setOnTouchListener(listener);
return this;
}
}
}
}