简单自定义弹出框 Dialog PopupWindow

 简单调用弹出框

   new Alert.Builder(getContext())
                .setOnBackPressedListener(Alert::dismiss)
                .setWindowModeWidth(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
                .setContentViewResId(R.layout.dialog_selector_calendar)
                .createDialog()
                .clicked(R.id.dialog_cancel, (view, alert) -> alert.dismiss())
                .clicked(R.id.dialog_previous_month, (view, alert) -> alert.findViewById(R.id.calendar_view).onCalendarTransformation(-1))
                .clicked(R.id.dialog_previous_year, (view, alert) -> alert.findViewById(R.id.calendar_view).onCalendarTransformation(-12))
                .clicked(R.id.dialog_next_month, (view, alert) -> alert.findViewById(R.id.calendar_view).onCalendarTransformation(1))
                .clicked(R.id.dialog_next_year, (view, alert) -> alert.findViewById(R.id.calendar_view).onCalendarTransformation(12))
                .with(R.id.dialog_title, (TextView view, Alert alert) -> view.setText(alert.findViewById(R.id.calendar_view).getCalendarFormatMonth()))
                .with(R.id.calendar_view, (ArnoldCalendarView view, Alert alert) -> {
                    view.setCalendarBackground(ContextCompat.getColor(getView().getContext(), R.color.popup_background)).setCalendarWeekFontColor(ContextCompat.getColor(getView().getContext(), R.color.calendar_background)).setOnCalendarCurrentDateChangeListener((year, month, day) -> alert.text(R.id.dialog_title, year + "年" + month + "月"));
                })
                .clicked(R.id.dialog_confirm, (view, alert) -> alert.dismiss())
                .show();

弹出框代码 

package dialog;

import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Build;
import android.support.v4.util.SparseArrayCompat;
import android.support.v7.app.AlertDialog;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Adapter;
import android.widget.Checkable;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

/**
 * @author Arnold
 * @date 2019/4/2
 * @des
 */
public interface Alert {


    /**
     * 显示窗口
     */
    void show();

    /**
     * 取消
     */
    void cancel();


    /**
     * 是否显示
     *
     * @return
     */
    boolean isShowing();

    /**
     * 消失
     */
    void dismiss();

    /**
     * 添加view
     *
     * @param idResId
     * @param layoutResId
     * @return
     */
     V addView(int idResId, int layoutResId);

    /**
     * 添加view
     *
     * @param idResId
     * @param subView
     * @return
     */
     V addView(int idResId, View subView);

    /**
     * 添加tag
     *
     * @param idResId
     * @param object
     * @return
     */
     V tag(int idResId, Object object);

    /**
     * 设置图片资源
     *
     * @param idResId
     * @param res
     * @return
     */
     V image(int idResId, int res);

    /**
     * 设置显示方式
     *
     * @param idResId
     * @param visibility
     * @return
     */
     V visibility(int idResId, int visibility);

    /**
     * toggle按钮
     *
     * @param idResId
     * @return
     */
     V toggle(int idResId);

    /**
     * 添加透明度
     *
     * @param idResId
     * @param alpha
     * @return
     */
     V alpha(int idResId, float alpha);

    /**
     * 设置文字
     *
     * @param idResId
     * @param text
     * @return
     */
     V text(int idResId, String text);

    /**
     * 文字对齐方式
     *
     * @param idResId
     * @param gravity
     * @return
     */
     V textGravity(int idResId, int gravity);

    /**
     * 设置文字颜色
     *
     * @param idResId
     * @param color
     * @return
     */
     V textColor(int idResId, int color);

    /**
     * 添加文字类型
     *
     * @param idResId
     * @param typeface
     * @param style
     * @return
     */
     V typeface(int idResId, Typeface typeface, int style);

    /**
     * 添加文字类型
     *
     * @param idResId
     * @param typeface
     * @return
     */
     V typeface(int idResId, Typeface typeface);

    /**
     * 设置文字大小
     *
     * @param idResId
     * @param unit
     * @param size
     * @return
     */
     V textSize(int idResId, int unit, float size);

    /**
     * 设置文字大小
     * {@link android.util.TypedValue#COMPLEX_UNIT_SP}
     *
     * @param idResId
     * @param size
     * @return
     */
     V textSize(int idResId, float size);

    /**
     * 添加下划线
     *
     * @param idResId
     * @return
     */
     V textUnderline(int idResId);

    /**
     * 点击
     *
     * @param idResId
     * @param checked
     * @return
     */
     V checked(int idResId, boolean checked);

    /**
     * 选中
     *
     * @param idResId
     * @param selected
     * @return
     */
     V selected(int idResId, boolean selected);

    /**
     * 添加按钮事件
     *
     * @param idResId
     * @param listener
     * @return
     */
     V clicked(int idResId, OnActionClickListener listener);

    /**
     * 添加按钮改变事件
     *
     * @param idResId
     * @param listener
     * @return
     */
     V checkedChange(int idResId, CompoundButton.OnCheckedChangeListener listener);

    /**
     * 添加适配器
     *
     * @param idResId
     * @param adapter
     * @return
     */
     V adapter(int idResId, android.widget.ListAdapter adapter);

    /**
     * 添加
     *
     * @param idResId
     * @param action
     * @return
     */
     V with(int idResId, Action action);

    /**
     * item
     *
     * @param action
     * @return
     */
     V with(Action action);

    /**
     * 查找视图
     *
     * @param idResId
     * @param 
     * @return
     */
     V findViewById(int idResId);


    interface OnBackPressedListener {
        /**
         * 点击返回键
         *
         * @param alert
         */
        void onBackPressed(Alert alert);
    }


    interface OnDismissListener {
        /**
         * 消失
         *
         * @param alert
         */
        void onDismiss(Alert alert);
    }

    interface OnKeyListener {
        /**
         * 物理键按下监听
         *
         * @param alert
         * @param keyCode
         * @param event
         * @return
         */
        boolean onKey(Alert alert, int keyCode, KeyEvent event);
    }

    interface OnActionClickListener {
        /**
         * 确定
         *
         * @param view
         * @param alert
         */
        void onApplyClick(View view, Alert alert);
    }

    interface Action {
        /**
         * 自定义View
         *
         * @param v
         * @param alert
         */
        void apply(V v, Alert alert);
    }

    /**
     * @author Arnold
     * @date 2019/4/2
     * @des
     */
    class Dialog implements Alert, DialogInterface.OnKeyListener, DialogInterface.OnDismissListener {


        private AlertDialog dialog;
        private Builder builder;
        private SparseArrayCompat viewSparseArrayCompat;

        /**
         * @param 
         * @return
         */
        private  V findItemView() {
            return (V) builder.mContentView;
        }

        /**
         * 查找视图
         *
         * @param idResId
         * @param 
         * @return
         */
        @Override
        public  V findViewById(int idResId) {
            View view = this.viewSparseArrayCompat.get(idResId);
            if (view == null) {
                view = this.builder.mContentView.findViewById(idResId);
                this.viewSparseArrayCompat.put(idResId, view);
            }
            return (V) view;
        }

        /**
         * 获取 实现Checkable的View
         *
         * @param idResId
         * @param 
         * @return
         */
        private  V findCheckableViewById(int idResId) {
            return this.findViewById(idResId);
        }

        protected Dialog(Builder builder) {
            this.viewSparseArrayCompat = new SparseArrayCompat<>();
            this.builder = builder;
            this.dialog = new AlertDialog
                    .Builder(builder.context)
                    .setView(builder.mContentView)
                    .setCancelable(builder.cancelable)
                    .create();
            this.dialog.setCanceledOnTouchOutside(builder.outsideTouchable);
            this.dialog.setOnKeyListener(this);
            this.dialog.setOnDismissListener(this);
        }

        @Override
        public void show() {
            dialog.show();
            //获得dialog的window窗口
            android.view.Window window = this.dialog.getWindow();
            //设置dialog在屏幕底部
            window.setGravity(builder.gravity);
            //设置dialog弹出时的动画效果,从屏幕底部向上弹出
            //去掉dialog默认的内填充
            window.getDecorView().setPadding(0, 0, 0, 0);
            //获得window窗口的属性
            WindowManager.LayoutParams layoutParams = window.getAttributes();
            layoutParams.width = builder.windowModeWidth;
            //设置窗口高度为包裹内容
            layoutParams.height = builder.windowModeHeight;
            //将设置好的属性set回去
            window.setAttributes(layoutParams);

        }

        @Override
        public void cancel() {
            if (null != dialog) {
                dialog.cancel();
            }
        }

        @Override
        public boolean isShowing() {
            if (null != dialog) {
                return dialog.isShowing();
            }
            return false;
        }

        @Override
        public void dismiss() {
            if (null != dialog) {
                dialog.dismiss();
            }
        }


        @Override
        public Alert addView(int idResId, int layoutResId) {
            this.findViewById(idResId).addView(((LayoutInflater) builder.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(layoutResId, null));
            return this;
        }

        @Override
        public Alert addView(int idResId, View subView) {
            this.findViewById(idResId).addView(subView);
            return this;
        }

        @Override
        public Alert tag(int idResId, Object object) {
            this.findViewById(idResId).setTag(object);
            return this;
        }

        @Override
        public Alert image(int idResId, int res) {
            this.findViewById(idResId).setImageResource(res);
            return this;
        }

        @Override
        public Alert visibility(int idResId, int visibility) {
            this.findViewById(idResId).setVisibility(visibility);
            return this;
        }

        @Override
        public Alert toggle(int idResId) {
            this.findCheckableViewById(idResId).toggle();
            return this;
        }

        @Override
        public Alert alpha(int idResId, float alpha) {
            this.findViewById(idResId).setAlpha(alpha);
            return this;
        }

        @Override
        public Alert text(int idResId, String text) {
            this.findViewById(idResId).setText(text);
            return this;
        }

        @Override
        public Alert textGravity(int idResId, int gravity) {
            this.findViewById(idResId).setGravity(gravity);
            return this;
        }

        @Override
        public Alert textColor(int idResId, int color) {
            this.findViewById(idResId).setTextColor(color);
            return this;
        }

        @Override
        public Alert typeface(int idResId, Typeface typeface, int style) {
            this.findViewById(idResId).setTypeface(typeface, style);
            return this;
        }

        @Override
        public Alert typeface(int idResId, Typeface typeface) {
            this.findViewById(idResId).setTypeface(typeface);
            return this;
        }

        @Override
        public Alert textSize(int idResId, int unit, float size) {
            this.findViewById(idResId).setTextSize(unit, size);
            return this;
        }

        @Override
        public Alert textSize(int idResId, float size) {
            this.findViewById(idResId).setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
            return this;
        }

        @Override
        public Alert textUnderline(int idResId) {
            this.findViewById(idResId).getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);
            return this;
        }

        @Override
        public Alert checked(int idResId, boolean checked) {
            this.findCheckableViewById(idResId).setChecked(checked);
            return this;
        }

        @Override
        public Alert selected(int idResId, boolean selected) {
            this.findViewById(idResId).setSelected(selected);
            return this;
        }

        @Override
        public Alert clicked(int idResId, Alert.OnActionClickListener listener) {
            this.findViewById(idResId).setOnClickListener(v -> listener.onApplyClick(v, this));
            return this;
        }

        @Override
        public Alert checkedChange(int idResId, CompoundButton.OnCheckedChangeListener listener) {
            this.findViewById(idResId).setOnCheckedChangeListener(listener);
            return this;
        }


        @Override
        public Alert adapter(int idResId, ListAdapter adapter) {
            this.findViewById(idResId).setAdapter(adapter);
            return this;
        }


        @Override
        public  V with(int idResId, Alert.Action action) {
            action.apply(this.findViewById(idResId), this);
            return (V) this;
        }

        @Override
        public  V with(Alert.Action action) {
            action.apply(findItemView(), this);
            return (V) this;
        }

        @Override
        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK && null != builder.onBackPressedListener) {
                builder.onBackPressedListener.onBackPressed(this);
            }
            if (null != builder.onKeyListener) {
                return builder.onKeyListener.onKey(this, keyCode, event);
            }
            return false;
        }


        @Override
        public void onDismiss(DialogInterface dialog) {
            if (null != builder.onDismissListener) {
                builder.onDismissListener.onDismiss(this);
            }
        }


    }

    class Builder {

        private static final float WINDOW_MODE_RATIO = 0.8F;

        private int gravity = Gravity.BOTTOM;
        private int layoutResId = -1;
        private Context context;
        private View mContentView;
        private boolean cancelable = true;
        private boolean outsideTouchable = true;

        private Alert.OnBackPressedListener onBackPressedListener;
        private Alert.OnDismissListener onDismissListener;
        private Alert.OnKeyListener onKeyListener;

        public Builder setOnBackPressedListener(Alert.OnBackPressedListener onBackPressedListener) {
            this.onBackPressedListener = onBackPressedListener;
            return this;
        }

        public Builder setOnKeyListener(Alert.OnKeyListener onKeyListener) {
            this.onKeyListener = onKeyListener;
            return this;
        }

        public Builder setOnDismissListener(Alert.OnDismissListener onDismissListener) {
            this.onDismissListener = onDismissListener;
            return this;
        }

        public Builder setWindowModeWidth(int windowModeWidth, int windowModeHeight) {
            this.windowModeWidth = windowModeWidth;
            this.windowModeHeight = windowModeHeight;
            return this;
        }

        private int windowModeWidth = ViewGroup.LayoutParams.WRAP_CONTENT, windowModeHeight = ViewGroup.LayoutParams.WRAP_CONTENT;

        public Builder setGravity(int gravity) {
            this.gravity = gravity;
            return this;
        }

        public Builder setContentView(View view) {
            this.mContentView = view;
            return this;
        }

        public Builder setContentViewResId(int layoutResId) {
            this.layoutResId = layoutResId;
            return this;
        }

        public Builder(Context context) {
            this.context = context;
        }

        public Builder setOutsideTouchable(boolean touchable) {
            outsideTouchable = touchable;
            return this;
        }

        /**
         * 设置对话框是否可取消。默认值为true。
         *
         * @param cancelable
         */
        public Builder setCancelable(boolean cancelable) {
            this.cancelable = cancelable;
            return this;
        }

        /**
         * 创建Dialog
         *
         * @return
         */
        public Alert createDialog() {
            if (null == mContentView) {
                if (layoutResId != -1) {
                    this.mContentView = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(layoutResId, null);
                } else {
                    this.mContentView = new FrameLayout(context);
                    this.mContentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                }
            }
            if (windowModeWidth != -1) {
                int displayWidth;
                Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    displayWidth = display.getMode().getPhysicalWidth();
                } else {
                    displayWidth = display.getWidth();
                }
                this.windowModeWidth = (int) (displayWidth * WINDOW_MODE_RATIO);
            }

            return new Dialog(this);
        }
    }

}

 

你可能感兴趣的:(视图)