一个封装好的仿ios风格的选择对话框

说起来毕业也一年半了,一直想把积累的一些东西搬到博客上来但找不到什么时间(其实是因为懒,>_<),现在有点时间就做一些吧,万事开头难,嘿嘿。

 

今天带来一个自定义控件叫IosDialog,就是ios上那种风格的有一个确定键一个返回键的文本提示对话框。控件是很早以前写的,之所以写这个控件是因为UI在做效果图的时候总是参照ios的风格来做,而ios那边有现成的控件,android这边我觉得每次都copy一大段的代码太麻烦了,于是就封装了这个控件。废话说了一堆,下面正片开始。

 

先自定义一个对话框风格,在styles文件下添加如下代码:

<!-- 自定义对话框风格 -->
<style name="CustomDialog" parent="@android:style/Theme.Dialog">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
    <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowNoTitle">true</item>
</style>

然后要定义一些对话框的背景资源文件,比如白色圆角背景,按钮的selector什么的,代码如下:

dialog_top_up.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3ffffff" />

    <corners
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp" />

</shape>

dialog_bottom_left_up.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3ffffff" />

    <corners android:bottomLeftRadius="10dp" />

</shape>

dialog_bottom_left_down.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3eeeeee" />

    <corners android:bottomLeftRadius="10dp" />

</shape>

dialog_bottom_left_selector.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/dialog_bottom_left_up" android:state_pressed="false"></item>
    <item android:drawable="@drawable/dialog_bottom_left_down" android:state_pressed="true"></item>

</selector>

dialog_bottom_right_up.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3ffffff" />

    <corners android:bottomRightRadius="10dp" />

</shape>

dialog_bottom_right_down.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#e3eeeeee" />

    <corners android:bottomRightRadius="10dp" />

</shape>

dialog_bottom_right_selector.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/dialog_bottom_right_up" android:state_pressed="false"></item>
    <item android:drawable="@drawable/dialog_bottom_right_down" android:state_pressed="true"></item>

</selector>

以上一共7个xml文件都添加到drawable目录下就可以了,没什么好讲的。


然后在layout目录下新建一个对话框的布局文件dialog_ios.xml,如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/dialog_top_up"
        android:gravity="center_horizontal"
        android:orientation="vertical">

        <TextView
            android:id="@+id/title_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="20dp"
            android:text="我是标题"
            android:textColor="#4a4a4a"
            android:textSize="18sp" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="40dp"
            android:padding="20dp">

            <TextView
                android:id="@+id/content_textview"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="我是文字"
                android:textColor="#666666"
                android:textSize="16sp" />

        </RelativeLayout>

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#dddddd" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/cancel_button"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:background="@drawable/dialog_bottom_left_selector"
            android:gravity="center"
            android:text="取消"
            android:textColor="#1e90ff"
            android:textSize="16sp" />

        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="#dddddd" />

        <Button
            android:id="@+id/asure_button"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:background="@drawable/dialog_bottom_right_selector"
            android:gravity="center"
            android:text="确定"
            android:textColor="#1e90ff"
            android:textSize="16sp" />

    </LinearLayout>

</LinearLayout>


以上准备工作都弄完以后就可以上控件IosDialog的本体了,如下:

public class IosDialog extends Dialog {
    private Context context;

    private TextView titleTextView;
    private TextView contentTextView;
    private Button cancelButton;
    private Button asureButton;
    private View view;

    //标题
    private String title;

    //内容
    private String text;

    //确定按钮的文字
    private String asureText;

    //取消按钮是的文字
    private String cancelText;

    //对话框位于屏幕位置
    private int gravity;

    //标题大小
    private int titleTextSize;

    //标题颜色
    private int titleTextColor;

    //内容大小
    private int textSize;

    //内容颜色
    private int textColor;

    //确定和取消按钮文字大小
    private int buttonTextSize;

    //确定按钮文字颜色
    private int buttonAsureTextColor;

    //取消按钮文字颜色
    private int buttonCancelTextColor;

    //对话框宽度
    private int width;

    //对话框高度
    private int height;

    //确定和取消按钮点击回调接口
    private OnButtonClickListener listener;

    public IosDialog(Context context) {
        super(context, R.style.CustomDialog);
        this.context = context;
    }

    public IosDialog(Context context, int theme) {
        super(context, theme);
        this.context = context;
    }

    public IosDialog createDialog() {
        view = LayoutInflater.from(context).inflate(R.layout.dialog_ios, null);

        titleTextView = (TextView) view.findViewById(R.id.title_textview);
        contentTextView = (TextView) view.findViewById(R.id.content_textview);
        cancelButton = (Button) view.findViewById(R.id.cancel_button);
        asureButton = (Button) view.findViewById(R.id.asure_button);
        titleTextView.setVisibility(title != null ? View.VISIBLE : View.GONE);
        titleTextView.setText(title);
        titleTextView.setTextColor(titleTextColor != 0 ? titleTextColor : Color.parseColor("#4a4a4a"));
        titleTextView.setTextSize(titleTextSize != 0 ? titleTextSize : 18);
        contentTextView.setText(text);
        contentTextView.setTextColor(textColor != 0 ? textColor : Color.parseColor("#666666"));
        contentTextView.setTextSize(textSize != 0 ? textSize : 16);
        cancelButton.setText(cancelText != null ? cancelText : "取消");
        cancelButton.setTextColor(buttonCancelTextColor != 0 ? buttonCancelTextColor : Color.parseColor("#1e90ff"));
        cancelButton.setTextSize(buttonTextSize != 0 ? buttonTextSize : 16);
        asureButton.setText(asureText != null ? asureText : "确定");
        asureButton.setTextColor(buttonAsureTextColor != 0 ? buttonAsureTextColor : Color.parseColor("#1e90ff"));
        asureButton.setTextSize(buttonTextSize != 0 ? buttonTextSize : 16);
        cancelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null) listener.onCancelClick();
            }
        });
        asureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null) listener.onAsureClick();
            }
        });

        show();
        setContentView(view);
        getWindow().getAttributes().gravity = gravity != 0 ? gravity : Gravity.CENTER;
        getWindow().setLayout(width != 0 ? width : getWindowWidth((Activity) context)
                - 2 * dp2px(45), height != 0 ? height : WindowManager.LayoutParams.WRAP_CONTENT);
        setCanceledOnTouchOutside(false);
        setCancelable(true);

        return this;
    }

    public void setAsureText(String asureText) {
        this.asureText = asureText;
    }

    public void setButtonAsureTextColor(int buttonAsureTextColor) {
        this.buttonAsureTextColor = buttonAsureTextColor;
    }

    public void setButtonCancelTextColor(int buttonCancelTextColor) {
        this.buttonCancelTextColor = buttonCancelTextColor;
    }

    public void setButtonTextSize(int buttonTextSize) {
        this.buttonTextSize = buttonTextSize;
    }

    public void setCancelText(String cancelText) {
        this.cancelText = cancelText;
    }

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

    public void setTitleTextSize(int titleTextSize) {
        this.titleTextSize = titleTextSize;
    }

    public void setTitleTextColor(int titleTextColor) {
        this.titleTextColor = titleTextColor;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }

    public void setTextSize(int textSize) {
        this.textSize = textSize;
    }

    public void setView(View view) {
        this.view = view;
    }

    public void setDialogSize(int width, int height) {
        this.width = width;
        this.height = height;
    }

    public interface OnButtonClickListener {
        void onAsureClick();

        void onCancelClick();
    }

    public void setOnButtonClickListener(OnButtonClickListener listener) {
        this.listener = listener;
    }

    private int getWindowWidth(Activity activity) {
        WindowManager windowManager = activity.getWindowManager();
        Display display = windowManager.getDefaultDisplay();
        return display.getWidth();
    }

    private int dp2px(float dipValue) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    public static class DialogBuilder {
        IosDialog dialog;

        public DialogBuilder(Context context) {
            dialog = new IosDialog(context);
        }

        /**
         * 设置对话框在屏幕的位置
         * @param gravity 类Gravity下的位置常数
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setGravity(int gravity) {
            dialog.setGravity(gravity);

            return this;
        }

        /**
         * 设置确定按钮文字
         * @param asureText 文字内容
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setAsureText(String asureText) {
            dialog.setAsureText(asureText);
            return this;
        }

        /**
         * 设置确定按钮文字颜色
         * @param buttonAsureTextColor 颜色值
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setButtonAsureTextColor(int buttonAsureTextColor) {
            dialog.setButtonAsureTextColor(buttonAsureTextColor);
            return this;
        }

        /**
         * 设置取消按钮文字颜色
         * @param buttonCancelTextColor 颜色值
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setButtonCancelTextColor(int buttonCancelTextColor) {
            dialog.setButtonCancelTextColor(buttonCancelTextColor);
            return this;
        }

        /**
         * 设置确定和取消按钮的文字大小
         * @param buttonTextSize 文字大小,单位sp
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setButtonTextSize(int buttonTextSize) {
            dialog.setButtonTextSize(buttonTextSize);
            return this;
        }

        /**
         * 设置取消按钮文字
         * @param cancelText 文字内容
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setCancelText(String cancelText) {
            dialog.setCancelText(cancelText);
            return this;
        }

        /**
         * 设置对话框大小
         * @param width   对话框宽度,单位px
         * @param height  对话框高度,单位px
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setDialogSize(int width, int height) {
            dialog.setDialogSize(width, height);
            return this;
        }

        /**
         * 设置标题大小
         * @param titleTextSize 文字大小,单位sp
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setTitleTextSize(int titleTextSize) {
            dialog.setTextSize(titleTextSize);
            return this;
        }

        /**
         * 设置标题颜色
         * @param titleTextColor 颜色值
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setTitleTextColor(int titleTextColor) {
            dialog.setTitleTextColor(titleTextColor);
            return this;
        }

        /**
         * 设置标题
         * @param title 文字内容
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setTitle(String title) {
            dialog.setTitle(title);
            return this;
        }

        /**
         * 设置内容
         * @param text 文字内容
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setText(String text) {
            dialog.setText(text);
            return this;
        }

        /**
         * 设置内容颜色
         * @param textColor 颜色值
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setTextColor(int textColor) {
            dialog.setTextColor(textColor);
            return this;
        }

        /**
         * 设置内容大小
         * @param textSize 文字大小,单位sp
         * @return 当前的DialogBuilder
         */
        public DialogBuilder setTextSize(int textSize) {
            dialog.setTextSize(textSize);
            return this;
        }

        /**
         * 设置确定和取消按钮的点击回调
         * @param listener 回调接口
         * @return 当前的DialogBuilder
         */
        public DialogBuilder addListener(OnButtonClickListener listener) {
            dialog.setOnButtonClickListener(listener);
            return this;
        }

        /**
         * 创建对话框,放在最后执行
         * @return 创建的IosDialog实体
         */
        public IosDialog create() {
            return dialog.createDialog();
        }
    }
}

这里稍微说明一下,控价引用建造者模式的思想,通过创建内部类DialogBuilder(建造者)的实体,设置好相关参数后调用它下面的create方法即可,相关参数个方法的意义已经在注释里写的很清楚了,不再累述。


最后就可以调用了。贴上MainActivity的代码:
public class MainActivity extends Activity {
    private Button button;

    private IosDialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
    }

    private void initData() {

    }

    private void initView() {
        button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialog();
            }
        });
    }仿ios风格

    private void showDialog() {
        dialog = new IosDialog.DialogBuilder(this)
                .setText("嫁给我好吗?")
                .addListener(new IosDialog.OnButtonClickListener() {
                    @Override
                    public void onAsureClick() {
                        Toast.makeText(MainActivity.this, "太好了", Toast.LENGTH_SHORT).show();
                        dialog.dismiss();
                    }

                    @Override
                    public void onCancelClick() {
                        Toast.makeText(MainActivity.this, "悲伤的故事", Toast.LENGTH_SHORT).show();
                        dialog.dismiss();
                    }
                })
                .create();
    }
}

这里稍微说明一下,控价引用建造者模式的思想,通过创建内部类DialogBuilder(建造者)的实体,设置好相关参数后调用它下面的create方法即可,相关参数个方法的意义已经在注释里写的很清楚了,不再累述。


最后就可以调用了。贴上MainActivity的代码:

public class MainActivity extends Activity {
    private Button button;

    private IosDialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
    }

    private void initData() {

    }

    private void initView() {
        button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialog();
            }
        });
    }

    private void showDialog() {
        dialog = new IosDialog.DialogBuilder(this)
                .setText("嫁给我好吗?")
                .addListener(new IosDialog.OnButtonClickListener() {
                    @Override
                    public void onAsureClick() {
                        Toast.makeText(MainActivity.this, "太好了", Toast.LENGTH_SHORT).show();
                        dialog.dismiss();
                    }

                    @Override
                    public void onCancelClick() {
                        Toast.makeText(MainActivity.this, "悲伤的故事", Toast.LENGTH_SHORT).show();
                        dialog.dismiss();
                    }
                })
                .create();
    }
}

布局文件activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_margin="10dp"
        android:text="SHOW DIALOG" />

</LinearLayout>

只有一个按钮。


最简单的调用方法只需要new IosDialog.DialogBuilder(this)创建一个DialogBuilder的实体,然后.setText设置文字内容,然后.addListener添加一个按钮点击的回调,最后.create(),一个对话框就弹出来了,效果如下:

                                                               

控件支持设置更多的自定义属性,比如在原来的代码上添加:

dialog = new IosDialog.DialogBuilder(this)
        ...

        .setAsureText("嗯")
        .setCancelText("你是个好人")
        .setTextColor(Color.parseColor("#bc8f8f"))
        
        ...
        .create();

就可以改变按钮的文字内容和说明文字的颜色,效果如下:

                                                                

控件还支持添加一个标题,使用setTitle方法(不设置标题时标题栏自动隐藏),添加如下代码:

dialog = new IosDialog.DialogBuilder(this)
       ...

        .setButtonCancelTextColor(Color.parseColor("#aaaaaa"))
        .setTitle("求婚大作战")
       
        ...
        .create();

再次运行,效果如下:

                                                                

更多设置方法的含义在控件源码中都有详细说明,大家可以自己试一试。

 

总结一下控件的用法就是:new一个DialogBulder,根据需要set一堆东西,最后create一下。是不是很简单?建造者模式真是懒人的福利,哈哈哈。


最后附上源码地址:点击打开链接


这次的内容就到这里,我们下次再见


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值