美文网首页
Android 使用Builder设计模式打造通用的Dialog

Android 使用Builder设计模式打造通用的Dialog

作者: Sky_Blue | 来源:发表于2017-12-27 20:26 被阅读237次
    一、Builder设计模式的定义
    将一个复杂对象的构建和它的表现分离,使得同样的构建过程,可以创建不同的表示。
    
    二、Android使用系统的Dialog
    //1.得到对话框的构造器,可以构造对话的模版
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("标题");
    builder.setMessage("包含内容");
    //2.添加一个确定按钮
    builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
    
        }
    });
    //3.添加一个取消按钮
    builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
    
        }
    });
    //4.使用构造器创建一个对话框的对象
    AlertDialog dialog = builder.create();
    //5.显示对话框
    dialog.show();
    
    三、安际开发情况
    由于每个APP的风格不一样,UI设计的弹窗五花八门,系统的Dialog用得不多。系统的Dialog定制性不强等等。
    由于系统的Dialog有诸多的不便,自己写一个通用的可定制的Dialog就是必要的了。
    
    四、Dialog都有哪些通用特性?
    1.Dialog的显示动画、位置,常用的是由下面出来和中间出来。
    2.Dialog的背景,包括背景色、背景圆角。
    3.其它的一些设置,用Dialog系统有的就行了,比如取消监听等等
    
    五、Dialog的Builder控制建造类,主要是设置Dialog构建的一些参数。
    /**
     * Dialog的Builder控制建造类
     */
    public class QuickBuilder {
        private QuickDialog mDialog;
        public boolean mCancelable = true;
        public DialogInterface.OnCancelListener mOnCancelListener;
        public DialogInterface.OnDismissListener mOnDismissListener;
        public DialogInterface.OnKeyListener mOnKeyListener;
        /**
         * Dialog的View 与Dialog的布局ID 设置一个即可
         */
        public View mView;
        /**
         * Dialog的View 与Dialog的布局ID 设置一个即可
         */
        public int mViewLayoutResId;
        /**
         * 存放文本的集合
         */
        public SparseArray<CharSequence> mTextArray = new SparseArray<>();
        /**
         * 存放点击事件的集合
         */
        public SparseArray<View.OnClickListener> mClickArray = new SparseArray<>();
        /**
         * 宽,默认是屏幕的宽
         */
        public int mWidth;
        public int mHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
        /**
         * 显示位置
         */
        public int mGravity = Gravity.CENTER;
        /**
         * 显示动画
         */
        public int mAnimation;
        /**
         * 宽,默认缩放
         */
        public float mScale = 0.85f;
        /**
         * 背景圆角,默认5
         */
        public int mBgRadius = 5;
        /**
         * 背景色,默认白色
         */
        public int mBgColor = Color.parseColor("#ffffffff");
        /**
         * 是否模糊
         */
        public boolean isDimEnabled = true;
    
    
        private QuickBuilder(Context context, int themeResId) {
            DisplayMetrics dm = context.getResources().getDisplayMetrics();
            mWidth = dm.widthPixels;
            this.mDialog = new QuickDialog(context, themeResId);
        }
    
        private QuickBuilder(Context context) {
            // 默认主题,在style配置,下面给出
            this(context, R.style.Theme_Dialog);
        }
    
        public static QuickBuilder create(Context context, int themeResId) {
            return new QuickBuilder(context, themeResId);
        }
    
        public static QuickBuilder create(Context context) {
            return new QuickBuilder(context);
        }
    
        public QuickBuilder setText(int viewId, CharSequence text) {
            mTextArray.put(viewId, text);
            return this;
        }
    
        public QuickBuilder setOnClickListener(int viewId, View.OnClickListener onClickListener) {
            mClickArray.put(viewId, onClickListener);
            return this;
        }
    
        /**
         * 设置显示的View
         */
        public QuickBuilder setContentView(int layoutResId) {
            mView = null;
            mViewLayoutResId = layoutResId;
            return this;
        }
    
        /**
         * 设置显示的布局
         */
        public QuickBuilder setContentView(View view) {
            mView = view;
            mViewLayoutResId = 0;
            return this;
        }
    
        /**
         * 设置ContentView背景的颜色:默认白色
         */
        public QuickBuilder setContentViewBgColor(int resId) {
            mBgColor = resId;
            return this;
        }
    
        /**
         * 设置ContentView背景的圆角:默认10dp
         *
         * @param radus 内部已转成dp
         * @return
         */
        public QuickBuilder setContentViewBgRadius(int radus) {
            mBgRadius = radus;
            return this;
        }
    
        /**
         * 设置背景是否模糊:默认是模糊的
         *
         * @param isDimEnabled
         * @return
         */
        public QuickBuilder setIsDimEnabled(boolean isDimEnabled) {
            this.isDimEnabled = isDimEnabled;
            return this;
        }
    
        /**
         * 设置宽度占满的比例
         */
        public QuickBuilder setWidthScale(float scale) {
            mScale = scale;
            return this;
        }
    
        public QuickBuilder fullWidth() {
            mScale = 1.0f;
            return this;
        }
    
        public QuickBuilder fromBottom(boolean isAnim) {
            if (isAnim) {
                mAnimation = R.style.Anim_Dialog_Bottom;
            }
            mGravity = Gravity.BOTTOM;
            return this;
        }
    
        public QuickBuilder setAnimation(int resId) {
            mAnimation = resId;
            return this;
        }
    
    
        public QuickBuilder setWidth(int width) {
            mWidth = width;
            return this;
        }
    
        public QuickBuilder setHeight(int height) {
            mHeight = height;
            return this;
        }
    
        /**
         * 设置点击空白是否消失
         */
        public QuickBuilder setCancelable(boolean cancelable) {
            mCancelable = cancelable;
            return this;
        }
    
        /**
         * 设置取消的监听
         */
        public QuickBuilder setOnCancelListener(DialogInterface.OnCancelListener onCancelListener) {
            mOnCancelListener = onCancelListener;
            return this;
        }
    
        /**
         * 设置Dialog消息的监听
         */
        public QuickBuilder setOnDismissListener(DialogInterface.OnDismissListener onDismissListener) {
            mOnDismissListener = onDismissListener;
            return this;
        }
    
        /**
         * 设置按键的监听
         */
        public QuickBuilder setOnKeyListener(DialogInterface.OnKeyListener onKeyListener) {
            mOnKeyListener = onKeyListener;
            return this;
        }
    
        public QuickDialog create() {
            mDialog.apply(this);
            return mDialog;
        }
    
        public QuickDialog show() {
            QuickDialog dialog = create();
            dialog.show();
            return dialog;
        }
    }
    
    六、Dialog View显示的辅助类,主要是加载View布局和找到里面的View等
    /**
     * Dialog View显示的辅助类
     */
    public class ViewHelper {
        /**
         * Dialog显示的View
         */
        private View mContentView;
        private SparseArray<WeakReference<View>> mViews = new SparseArray<>();
    
        public ViewHelper(Context context, int layoutResId) {
            mContentView = LayoutInflater.from(context).inflate(layoutResId, null);
        }
    
        public ViewHelper(View mView) {
            mContentView = mView;
        }
        public View getContentView() {
            return mContentView;
        }
        /**
         * 设置文本
         */
        public void setText(int viewId, CharSequence charSequence) {
            TextView tv = getView(viewId);
            if (tv != null && charSequence != null) {
                tv.setText(charSequence);
            }
        }
        public <T extends View> T getView(int viewId) {
            WeakReference<View> viewWeakReference = mViews.get(viewId);
            View view = null;
            if (viewWeakReference == null) {
                view = mContentView.findViewById(viewId);
                if (view != null) {
                    mViews.put(viewId, new WeakReference<>(view));
                }
            } else {
                view = viewWeakReference.get();
            }
            return (T) view;
        }
        /**
         * 设置点击事件
         */
        public void setOnClickListener(int viewId, View.OnClickListener onClickListener) {
            View view = getView(viewId);
            if (view != null && onClickListener != null) {
                view.setOnClickListener(onClickListener);
            }
        }
    }
    
    六、自定义通用的Dialog
    /**
     * 自定义通用的Dialog
     */
    public class QuickDialog extends Dialog {
        private ViewHelper mViewHelper = null;
        public QuickDialog(@NonNull Context context, @StyleRes int themeResId) {
            super(context, themeResId);
        }
    
        /**
         * 绑定和设置参数
         */
        public QuickDialog apply(QuickBuilder params) {
            // 1.设置布局
            mViewHelper = null;
            if (params.mViewLayoutResId != 0) {
                mViewHelper = new ViewHelper(getContext(), params.mViewLayoutResId);
            }
            if (params.mView != null) {
                mViewHelper = new ViewHelper(params.mView);
            }
            if (mViewHelper == null) {
                throw new IllegalArgumentException("请调用setContentView方法设置布局");
            }
            // 创建前景和圆角
            final GradientDrawable bg = new GradientDrawable();
            float radius = dp2px(params.mBgRadius);
            bg.setCornerRadii(new float[]{radius, radius, radius, radius, radius, radius, radius, radius});// 1 2 3 4(顺时针)
            bg.setColor(params.mBgColor);
            // 设置背景
            View contentView = mViewHelper.getContentView();
            // 设置Dialog的布局
            setContentView(contentView);
            // 设置背景
            contentView.setBackgroundDrawable(bg);
            // 是否可以取消
            setCancelable(params.mCancelable);
            // 设置监听
            if (params.mOnCancelListener != null) {
                setOnCancelListener(params.mOnCancelListener);
            }
            if (params.mOnDismissListener != null) {
                setOnDismissListener(params.mOnDismissListener);
            }
            if (params.mOnKeyListener != null) {
                setOnKeyListener(params.mOnKeyListener);
            }
    
            Window window = getWindow();
            // 显示的位置
            window.setGravity(params.mGravity);
            // 动画
            if (params.mAnimation != 0) {
                window.setWindowAnimations(params.mAnimation);
            }
            // 宽高
            WindowManager.LayoutParams windowAttributes = window.getAttributes();
            windowAttributes.width = (int) (params.mWidth * params.mScale);
            windowAttributes.height = params.mHeight;
            window.setAttributes(windowAttributes);
            // 设置背景是否模糊
            if (!params.isDimEnabled) {
                window.setDimAmount(0f);
            }
            // 设置文本
            int textSize = params.mTextArray.size();
            for (int i = 0; i < textSize; i++) {
                mViewHelper.setText(params.mTextArray.keyAt(i), params.mTextArray.valueAt(i));
            }
            // 设置点击
            int clickSize = params.mClickArray.size();
            for (int i = 0; i < clickSize; i++) {
                mViewHelper.setOnClickListener(params.mClickArray.keyAt(i), params.mClickArray.valueAt(i));
            }
            return this;
        }
    
        public int dp2px(float dp) {
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getContext().getResources().getDisplayMetrics());
        }
    
        public void setText(int viewId, CharSequence text) {
            mViewHelper.setText(viewId, text);
        }
    
        public void setOnClickListener(int viewId, View.OnClickListener onClickListener) {
            mViewHelper.setOnClickListener(viewId, onClickListener);
        }
    
        public <T extends View> T getView(int viewId) {
            return mViewHelper.getView(viewId);
        }
    }
    
    七、Dialog默认显示的主题
     <!--从下弹出来的基本动画-->
        <style name="Anim_Dialog_Bottom" parent="@style/Theme.AppCompat.Dialog">
            <item name="android:windowEnterAnimation">@anim/slide_in</item>
            <item name="android:windowExitAnimation">@anim/slide_out</item>
        </style>
    
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <!--slide_in-->
        <translate
            android:duration="250"
            android:fromXDelta="0"
            android:fromYDelta="100%"
            android:toXDelta="0"
            android:toYDelta="0" />
    </set>
    
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <!--slide_out-->
        <translate
            android:duration="250"
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:toXDelta="0"
            android:toYDelta="100%" />
    </set>
    
    八、Dialog的使用
    QuickDialog dialog = QuickBuilder.create(this)
            .setContentView(R.layout.dialog_loading)
            .fromBottom(true)
            .setCancelable(false)
            .setIsDimEnabled(false)
            .create();
            // 设置Dialog布局里面View的点击事件,文本设置一样
            dialog.setOnClickListener(R.id.dialog_message, new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    
                }
            });
            dialog.show();
    

    用起来感觉简单多了,也可以根据UI定制一些APP通用的Dialog。

    相关文章

      网友评论

          本文标题:Android 使用Builder设计模式打造通用的Dialog

          本文链接:https://www.haomeiwen.com/subject/npljvxtx.html