简洁仿IOS的圆角Dialog

先上个效果图 ,也可以根据自己需求,添加控件,也可以根据这种思路,自己去修改布局文件。

最后会给出源码githup地址。


简洁仿IOS的圆角Dialog_第1张图片

然后开始吧。
首先在styles文件里定义样式。


接着再drawable文件夹下自定义一个圆角的shape.






    

    


然后自定义一个dialog的xml布局, 并且设置背景引用圆角shape。
android:background="@drawable/bg_course_dialog"
布局文件代码如下:





    

    

    

        
    


    

    

        

        

        
    


然后是封装的具体代码。
这里使用alertdialog中的建造者模式Builder来建造,这样可以方便我们建造不同需求的dialog。(如对建造者模式不了解的可以自己搜一下相关资料)

代码很简单 首先是构造一个Params来管理我们具体要build的属性。

public static class Builder implements BuilderInterface {
    private Context mContext;
    private final ControllerParams mParams;
    private Controller mController;

    public Builder(Context context) {
        mContext = context;
        mParams = new ControllerParams();
        mController = new Controller(mContext);
    }

    public Builder setContentView(int layoutId) {
        mParams.setLayoutId(layoutId);
        return this;
    }

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

    public Builder setTitle(String title) {
        mParams.setTitle(title);
        return this;
    }

    public Builder reSetTitle(String title) {
        mParams.setTitle(title);
        mController.setTitle(title);
        return this;
    }

    public Builder reSetMessage(String message) {
        mParams.setMessage(message);
        mController.setMessage(message);
        return this;
    }

    public Builder reSetIcon(int iconId) {
        mParams.setIconId(iconId);
        mController.setIcon(iconId);
        return this;
    }

    public Builder setMessage(String message) {
        mParams.setMessage(message);
        return this;
    }

    public Builder setIcon(int iconId) {
        mParams.setIconId(iconId);
        return this;
    }

    public Builder setCancelable(boolean cancelable) {
        mParams.setCancelable(cancelable);
        return this;
    }


    public Builder setNegativeButton(String text, OnNegativeListener listener) {
        mParams.setNegativeListener(listener);
        mParams.setNegativeText(text);

        return this;
    }

    public Builder setPositiveButton(String text,  OnPositiveListener listener)  {
        mParams.setPositiveListener(listener);
        mParams.setPositiveText(text);
        return this;
    }

    /**
     * 建造dialog
     * @return dialog
     */
    public Dialog create() {
        Dialog dialog = new Dialog(mContext, R.style.AlertDialogStyle);
        //属性交给controller去应用到dialog上
        mParams.apply(mController, dialog);
        return dialog;
    }

    /**
     * 建造一个默认的dialog
     * @param onPositiveListener 确认按键监听
     * @param onNegativeListener 取消按键监听
     * @return dialog
     */
    public Dialog createDefault(OnPositiveListener onPositiveListener, OnNegativeListener onNegativeListener) {
        Dialog dialog = new Dialog(mContext, R.style.AlertDialogStyle);
        build(onPositiveListener, onNegativeListener);
        mParams.apply(mController, dialog);
        return dialog;
    }

    private void build(OnPositiveListener onPositiveListener, OnNegativeListener onNegativeListener) {
        setTitle("温馨提示")
                .setMessage("确认提交吗")
                .setCancelable(false)
                .setPositiveButton("确认", onPositiveListener)
                .setNegativeButton("取消", onNegativeListener);
    }
}

管理属性的类核心方法就是apply(),在这里判断是否缓存了属性,有的话就交给controller去设置给dialog.

/**
 * 管理dialog所有属性的类
 */
private static class ControllerParams {
    private String mTitle;
    private String mMessage;
    private int mIconId = -1;
    private int mLayoutId = -1;
    private boolean mCancelable;
    private String mPositiveText;
    private String mNegativeText;
    private OnPositiveListener mPositiveListener;
    private OnNegativeListener mNegativeListener;
    private View mContentView;


    private void apply(Controller controller, Dialog dialog) {

        if (mContentView != null) {
            controller.setContentView(mContentView, dialog);
        }else {
            controller.setContentView(mLayoutId, dialog);
        }
        dialog.setCancelable(mCancelable);
        if (mCancelable) {
            dialog.setCanceledOnTouchOutside(true);
        }

        if (mTitle != null) {
            controller.setTitle(mTitle);
        }
        if (mMessage != null) {
            controller.setMessage(mMessage);
        }
        if (mPositiveText != null && mPositiveListener != null) {
            controller.setPositiveButton(mPositiveText, mPositiveListener);
        }
        if (mNegativeText != null && mNegativeListener != null) {
            controller.setNegativeButton(mNegativeText, mNegativeListener);
        }
        if (mIconId != -1) {
            controller.setIcon(mIconId);
        }


    }


    public int getLayoutId() {
        return mLayoutId;
    }

    private void setLayoutId(int layoutId) {
        mLayoutId = layoutId;
    }

    public String getTitle() {
        return mTitle;
    }

    private void setTitle(String title) {
        mTitle = title;
    }

    public String getMessage() {
        return mMessage;
    }

    private void setMessage(String message) {
        mMessage = message;
    }

    public int getIconId() {
        return mIconId;
    }

    private void setIconId(int iconId) {
        mIconId = iconId;
    }

    public boolean isCancelable() {
        return mCancelable;
    }

    private void setCancelable(boolean cancelable) {
        mCancelable = cancelable;
    }

    public String getPositiveText() {
        return mPositiveText;
    }

    private void setPositiveText(String positiveText) {
        mPositiveText = positiveText;
    }

    public String getNegativeText() {
        return mNegativeText;
    }

    private void setNegativeText(String negativeText) {
        mNegativeText = negativeText;
    }

    public OnPositiveListener getPositiveListener() {
        return mPositiveListener;
    }

    private void setPositiveListener(OnPositiveListener positiveListener) {
        mPositiveListener = positiveListener;
    }

    public OnNegativeListener getNegativeListener() {
        return mNegativeListener;
    }

    private void setNegativeListener(OnNegativeListener negativeListener) {
        mNegativeListener = negativeListener;
    }

    private void setContentView(View contentView) {
        mContentView = contentView;
    }
}

这里定义2个点击监听,用来回调dialog中确认和取消的点击。

/**
 * 确认按键监听
 */
public interface OnPositiveListener {
    void onPositive(Dialog dialog);

}

/**
 * 取消按键监听
 */
public interface OnNegativeListener {
    void onNegative(Dialog dialog);
}

这里controller中封装了最主要的代码,代码很简单,就是将上面写的dialog的 xml布局文件inflate出来设置给dialog,这也是封装好的默认的dialog 就跟一开始的效果图一样。
但是我们说了,我们有可能有其他需求,这时候就需要用builder.setcontentview将我们需要的具体的view或者layoutid传进来,这时候看代码,我们布局文件中的根布局ll_content就会将默认的message的textview remove掉,然后再把传进来的view添加进来,这就实现定制其他需求的View。

private static class Controller implements View.OnClickListener,BuilderInterface {
    private Context mContext;
    private TextView mTvTitle;
    private TextView mTvMessage;
    private TextView mTvPositive;
    private TextView mTvNegative;
    private ImageView mIvIcon;
    private View mHorizontalLine;
    private View mVerticalLine;
    private View mRootView;
    private OnNegativeListener mOnNegativeListener;
    private OnPositiveListener mOnPositiveListener;
    private Dialog mDialog;
    private View mContentView;
    private final LinearLayout mLlContent;


    private   Controller(Context context) {
        mContext = context;
        mRootView = View.inflate(mContext, R.layout.view_dialog_warm_tip, null);
        mLlContent = (LinearLayout) mRootView.findViewById(R.id.ll_content);
        mHorizontalLine = mRootView.findViewById(R.id.line_horizontal);
    }

    private void setContentView(int layoutResID, Dialog dialog) {
        if (layoutResID == -1) {

        } else {
            mContentView = View.inflate(mContext, layoutResID, null);
            mLlContent.removeAllViews();
            mLlContent.addView(mContentView);
        }
        mDialog = dialog;
        dialog.setContentView(mRootView, getPrams(mContext));
    }

    private void setContentView(View view, Dialog dialog) {
        mLlContent.removeAllViews();
        mLlContent.addView(view);
        mDialog = dialog;
        dialog.setContentView(mRootView, getPrams(mContext));
    }

    private FrameLayout.LayoutParams getPrams(Context context) {
        WindowManager windowManager = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        Display sDefaultDisplay = windowManager.getDefaultDisplay();

        return new FrameLayout.LayoutParams(
                (int) (sDefaultDisplay.getWidth() * 0.80f),
                ViewGroup.LayoutParams.WRAP_CONTENT);

    }


    public Controller setTitle(String title) {
        mTvTitle = (TextView) mRootView.findViewById(R.id.title);
        if (mTvTitle != null) {
            mTvTitle.setText(title);
        }
        return this;
    }

    public Controller setMessage(String message) {
        mTvMessage = (TextView) mRootView.findViewById(R.id.message);
        if (mTvMessage != null) {
            mTvMessage.setText(message);
        }
        return this;
    }

    public Controller setIcon(int iconId) {
        mIvIcon = (ImageView) mRootView.findViewById(R.id.icon);
        if (mIvIcon != null) {
            mIvIcon.setImageResource(iconId);
            mIvIcon.setVisibility(View.VISIBLE);
        }
        return this;
    }

    @Override
    public BuilderInterface setCancelable(boolean cancelable) {
        return null;
    }


    public Controller setNegativeButton(String negativeText, OnNegativeListener listener) {
        mTvNegative = (TextView) mRootView.findViewById(R.id.dialog_cancel);
        mVerticalLine = mRootView.findViewById(R.id.line_vertical);
        if (mTvNegative != null) {
            mTvNegative.setVisibility(View.VISIBLE);
            mTvNegative.setText(negativeText);
            setOnNegativeListener(listener);
            mHorizontalLine.setVisibility(View.VISIBLE);
            if (mTvPositive != null) {
                mVerticalLine.setVisibility(View.VISIBLE);
            }

        }
        return this;
    }

    public Controller setPositiveButton(String positiveText, OnPositiveListener listener) {
        mTvPositive = (TextView) mRootView.findViewById(R.id.dialog_commit);

        if (mTvPositive != null) {
            mTvPositive.setVisibility(View.VISIBLE);
            mTvPositive.setText(positiveText);
            setOnPositiveListener(listener);
            mHorizontalLine.setVisibility(View.VISIBLE);
        }
        return this;
    }

    private Controller setOnNegativeListener(OnNegativeListener onNegativeListener) {

        mOnNegativeListener = onNegativeListener;
        mTvNegative.setOnClickListener(this);
        return this;
    }

    private Controller setOnPositiveListener(OnPositiveListener onPositiveListener) {

        mOnPositiveListener = onPositiveListener;
        mTvPositive.setOnClickListener(this);
        return this;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.dialog_cancel:
                if (mOnNegativeListener != null) {
                    mOnNegativeListener.onNegative(mDialog);
                }
                break;
            case R.id.dialog_commit:
                if (mOnPositiveListener != null) {
                    mOnPositiveListener.onPositive(mDialog);
                }
                break;
        }
    }
}

到这里dialog的封装就完了,接下来看看activity中怎么使用。
使用方法就跟alertdialog一样。

 private void initDefaultDialog() {
        SherlockDialog.Builder builder = new SherlockDialog.Builder(this);
        mDialog = builder.createDefault(this, this);
//        builder.reSetTitle("重新设置Tiltle");
    }

    private void initEditDialog() {
        SherlockDialog.Builder builder = new SherlockDialog.Builder(this);

        EditText editText = new EditText(this);
        builder.setContentView(editText);
        mDialog = builder.createDefault(this, this);

    }

    private void initDialog() {

        SherlockDialog.Builder builder = new SherlockDialog.Builder(this);
        mDialog = builder.setTitle("温馨提示")
                .setMessage("确认提交吗?")
                .setPositiveButton("确认", new SherlockDialog.OnPositiveListener() {
                    @Override
                    public void onPositive(Dialog dialog) {
                        Toast.makeText(DialogActivity.this, "确认提交", Toast.LENGTH_SHORT).show();
                        dialog.dismiss();
                    }
                })
                .setNegativeButton("取消", new SherlockDialog.OnNegativeListener() {
                    @Override
                    public void onNegative(Dialog dialog) {
                        Toast.makeText(DialogActivity.this, "取消提交", Toast.LENGTH_SHORT).show();
                        dialog.dismiss();
                    }
                })
                .setIcon(R.mipmap.ic_launcher_round).create();
    }

    public void button1(View view) {
        initDialog();
        mDialog.show();
    }

    public void button2(View view) {

        initEditDialog();
        mDialog.show();
    }

    public void button3(View view) {
        initDefaultDialog();
        mDialog.show();
    }

    @Override
    public void onPositive(Dialog dialog) {
        dialog.dismiss();
    }

    @Override
    public void onNegative(Dialog dialog) {
        dialog.dismiss();
    }

可以看到跟系统自带的alertdialog的builder方法使用是一样的。

githup源码地址:
https://github.com/DarkSherlock/DialogBuilder

你可能感兴趣的:(简洁仿IOS的圆角Dialog)