关于自定义Dialog

  简单调用

            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;
            }
        }

    }

}

 

你可能感兴趣的:(横冲直撞)