美文网首页
动手写一个万能的 Dialog

动手写一个万能的 Dialog

作者: cao苗子 | 来源:发表于2019-08-22 09:54 被阅读0次

1.自定义一个mydialog继承dialog

使用builder设计模式,只需要传一个 layout 进去就行了。也可以自己定义主题模式,还有各种动画。
先看代码 一行代码就能显示出来:

final MyAlertDialog dialog = new MyAlertDialog.Builder(this)
                .setContentView(R.layout.dialog_layout)
                .setWidth(400)
                .setHeight(200)
                .create();
        dialog.show();

.Builder().set.set这中代码的风格就是链式的builder模式。现在这种很流行。

2.在dialog中建立一个内部类Builder

public static class Builder{
        private AlertParams P;
        private Context mContext;
        private int mThemeId;
        public Builder(Context context){
            this(context,R.style.dialog);
        }
        public Builder(Context context,int themeId){
            this.mContext = context;
            this.mThemeId = themeId;
            P = new AlertParams(context,themeId);
        }
        public Builder setContentView(int layoutId){
            P.mLayoutId = layoutId;
            return this;
        }
        public Builder setContentView(View view){
            P.mView = view;
            return this;
        }
        public Builder setAnimations(int animations){
            P.mAnimation = animations;
            return this;
        }
        public Builder setWidth(int width){
            P.mWidth = width;
            return this;
        }
        public Builder setHeight(int height){
            P.mHeight = height;
            return this;
        }
        public Builder fullWidth(){
            P.mWidth = ViewGroup.LayoutParams.MATCH_PARENT;
            return this;
        }
        public Builder setCanceledOnTouchOutside(boolean canceled){
            P.mCancelable = canceled;
            return this;
        }
        public MyAlertDialog create(){
            MyAlertDialog dialog = new MyAlertDialog(mContext,mThemeId);
            dialog.setCancelable(P.mCancelable);
            //绑定数据
            P.apply(dialog);
            //点击空白处消失
            if(P.mCancelable){
                dialog.setCanceledOnTouchOutside(true);
            }
            return dialog;
        }
    }

这个静态内部类主要是用来设置一些基本的属性,使用起来非常方便。

3.DialogParams 参数类

参数类没有什么可说的,就是dialog的属性定义。

public class AlertParams {
    //内容布局
    public View mView;
    //内容布局Id
    public int mLayoutId;
    public Context mContext;
    public int mThemeId;
    public int mHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
    public int mWidth = ViewGroup.LayoutParams.WRAP_CONTENT;
    public int mAnimation;
    public int mGravity = Gravity.CENTER;
    public boolean mCancelable;
    public AlertParams(Context context,int mThemeId){
        this.mContext = context;
        this.mThemeId = mThemeId;
    }
    /**
     * 设置数据
     */
    public void apply(MyAlertDialog dialog) {

        //设置布局
        MyAlertHelper myAlertHelper = null;
        if(mLayoutId != 0){
            myAlertHelper = new MyAlertHelper(mContext,mLayoutId);
        }
        if(mView != null){
            myAlertHelper = new MyAlertHelper(mContext,mView);
        }

        if(myAlertHelper == null){
            throw new IllegalArgumentException("请先设置布局dialog.setContentView");
        }

        dialog.setAlertHelper(myAlertHelper);

        //设置布局
        dialog.setContentView(myAlertHelper.getContentView());

        Window window = dialog.getWindow();

        WindowManager.LayoutParams attributes = window.getAttributes();

        attributes.width = mWidth;

        attributes.height = mHeight;

        window.setAttributes(attributes);

        if(mAnimation != 0){
            window.setWindowAnimations(mAnimation);
        }

        window.setGravity(mGravity);

    }
}

4.helper这是dialog的辅助类

这个是一个辅助类,主要是对dialog的view进行操作,比如加载试图,设置点击事件,设置文本等等,我这里只是写了一个getView(),很多都可以自己去实现。

public class MyAlertHelper{
    private View mView;
    private SparseArray<WeakReference<View>> mViews = new SparseArray<>();
    public MyAlertHelper(Context mContext, int mLayoutId) {
        this.mView = LayoutInflater.from(mContext).inflate(mLayoutId,null);
    }
    public MyAlertHelper(Context mContext, View mView) {
        this.mView = mView;
    }
    public View getContentView(){
        return this.mView;
    }

    /**
     * 获取view
     * @param viewId
     * @param <T>
     * @return
     */
    public <T extends View> T getViewById(int viewId){
        WeakReference<View> weakReference = mViews.get(viewId);
        View view = null;
        if(weakReference != null){
            view = weakReference.get();
        }
        if(view == null){
            view = this.mView.findViewById(viewId);
            mViews.put(viewId,new WeakReference<View>(view));
        }
        return (T) view;
    }
}

到这里就结束了。大家应该自己多去看看dialog的源码,也是这种builder模式,很多都是静态内部类的使用。使用起来非常的方便,也可以自己自定义一些自己想要的属性。
好了.
有问题随时问
qq:362976241

附上源码地址:
https://github.com/panshimu/BaseDialog

相关文章

网友评论

      本文标题:动手写一个万能的 Dialog

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