Android自定义Dialog

来源:互联网 发布:js获取下拉框选中的值 编辑:程序博客网 时间:2024/06/15 14:32

在项目中我们经常需要使用Dialog弹出一些信息告知用户或者指引用户做一些选择性操作。
Android系统提供了Dialog类,以及Dialog的子类,常见如AlertDialog来实现此类功能。但是不足之处有以下几点:
1. 基于Android提供的Dialog及其子类样式单一,风格上与App本身风格可能不太协调;
2. Dialog弹窗在布局和功能上有所限制,不一定能满足实际的业务需求。
基于以上不足所以我们会想自己定义Dialog进行展示,在这篇博文中后面的部分主要是界面方面的内容,有兴趣的博友可以一起探讨一下。下面就介绍我在项目中自定义的Dialog,先展示一下效果吧。
这里写图片描述 这里写图片描述
我们通过效果图可以看到这个自定义的对话框是圆角效果,title是喜庆的大红颜色,底部两个按钮一个是确认按钮另一个是取消按钮。风格呢各位博友可以自己根据喜爱进行修改,以下我要开始贴代码了(代码顺序:1.Java代码;2.layout文件;3.调用示例;4.资源文件(color、dimen、drable))


我们的CustomDialog继承自android.app.Dialog,里面通过静态内部类Builder来设置dialog的布局和属性,最后通过Builder来create一个CustomDialog对象,来看实现(代码里面有相应的注释)

package cn.dai.com.widget;import android.app.Dialog;import android.content.Context;import android.content.DialogInterface;import android.view.KeyEvent;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup.LayoutParams;import android.widget.Button;import android.widget.LinearLayout;import android.widget.TextView;import cn.dai.com.R;/********************************************************* * @类描述:  自定义dialog * @创建人: daizhenhong * @创建时间:2016-3-18 上午9:35:22 ***************************************************************************/public class CustomDialog extends Dialog {    public CustomDialog(Context context) {        super(context);    }    public CustomDialog(Context context, int theme) {        super(context, theme);    }    public CustomDialog setCloseOnTouchOutside(boolean flag) {        this.setCanceledOnTouchOutside(flag);        return this;    }    public static class Builder {        private Context context;        private String title;        private String message;        private String positiveButtonText;        private String negativeButtonText;        private View contentView;        /** 默认点击对话框外部可以关闭*/        private boolean enableCloseoutside = true;        /** 默认点击back键可以关闭对话框*/        private boolean enableCloseBackKey = true;        /** 默认可以取消*/        private boolean cancelable = true;        private DialogInterface.OnClickListener positiveButtonClickListener;        private DialogInterface.OnClickListener negativeButtonClickListener;        public Builder(Context context) {            this.context = context;        }        public Builder setMessage(String message) {            this.message = message;            return this;        }        /**         * Set the Dialog message from resource         *          * @param title         * @return         */        public Builder setMessage(int message) {            this.message = (String) context.getText(message);            return this;        }        /**         * Set the Dialog title from resource         *          * @param title         * @return         */        public Builder setTitle(int title) {            this.title = (String) context.getText(title);            return this;        }        /**         * Set the Dialog title from String         *          * @param title         * @return         */        public Builder setTitle(String title) {            this.title = title;            return this;        }        public Builder setContentView(View v) {            this.contentView = v;            return this;        }        /**         * Set the positive button resource and it's listener         *          * @param positiveButtonText         * @return         */        public Builder setPositiveButton(int positiveButtonText, DialogInterface.OnClickListener listener) {            this.positiveButtonText = (String) context.getText(positiveButtonText);            this.positiveButtonClickListener = listener;            return this;        }        public Builder setPositiveButton(String positiveButtonText, DialogInterface.OnClickListener listener) {            this.positiveButtonText = positiveButtonText;            this.positiveButtonClickListener = listener;            return this;        }        public Builder setNegativeButton(int negativeButtonText, DialogInterface.OnClickListener listener) {            this.negativeButtonText = (String) context.getText(negativeButtonText);            this.negativeButtonClickListener = listener;            return this;        }        public Builder setNegativeButton(String negativeButtonText, DialogInterface.OnClickListener listener) {            this.negativeButtonText = negativeButtonText;            this.negativeButtonClickListener = listener;            return this;        }        public Builder setCloseOnTouchOutside(boolean cancel) {            enableCloseoutside = cancel;            return this;        }        public Builder enableCloseOnBackKey(boolean enable) {            enableCloseBackKey = enable;            return this;        }        public Builder setCancelable(boolean cancel) {            cancelable = cancel;            return this;        }        public CustomDialog create() {            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);            // instantiate the dialog with the custom Theme            final CustomDialog dialog = new CustomDialog(context, R.style.Dialog);            // 装载自定义的布局文件dialog_normal.xml            View layout = inflater.inflate(R.layout.dialog_normal, null);            dialog.addContentView(layout, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));            // set the dialog title            ((TextView) layout.findViewById(R.id.title)).setText(title);            // set the confirm button            if (positiveButtonText != null) {                ((Button) layout.findViewById(R.id.positiveButton)).setText(positiveButtonText);                if (positiveButtonClickListener != null) {                    ((Button) layout.findViewById(R.id.positiveButton)).setOnClickListener(new View.OnClickListener() {                        public void onClick(View v) {                            positiveButtonClickListener.onClick(dialog, DialogInterface.BUTTON_POSITIVE);                        }                    });                }            } else {                // if no confirm button just set the visibility to GONE                layout.findViewById(R.id.positiveButton).setVisibility(View.GONE);            }            // set the cancel button            if (negativeButtonText != null) {                ((Button) layout.findViewById(R.id.negativeButton)).setText(negativeButtonText);                if (negativeButtonClickListener != null) {                    ((Button) layout.findViewById(R.id.negativeButton)).setOnClickListener(new View.OnClickListener() {                        public void onClick(View v) {                            negativeButtonClickListener.onClick(dialog, DialogInterface.BUTTON_NEGATIVE);                        }                    });                }            } else {                // if no confirm button just set the visibility to GONE                layout.findViewById(R.id.negativeButton).setVisibility(View.GONE);            }            // set the content message            if (message != null) {                ((TextView) layout.findViewById(R.id.message)).setText(message);            }             //如果通过setContentView设置了自定义的View布局,则将默认的内容控件移除,并添加设置的contentView(保持内容显示的灵活性,同时保留自定义Dialog头部和底部按钮的样式风格不变)            if (contentView != null) {                // if no message set                // add the contentView to the dialog body                ((LinearLayout) layout.findViewById(R.id.content)).removeAllViews();                ((LinearLayout) layout.findViewById(R.id.content)).addView(contentView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));            }            // set closeOnTouchOutside            dialog.setCanceledOnTouchOutside(enableCloseoutside);            dialog.setCancelable(cancelable);            dialog.setContentView(layout);            if (!enableCloseBackKey)                dialog.setOnKeyListener(new OnKeyListener() {                    @Override                    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {                        if (keyCode == KeyEvent.KEYCODE_BACK)                            return true;                        return false;                    }                });            return dialog;        }    }}

以上就是java代码段了,然后就是layout文件,其中会引用多个资源文件,需要先把资源文件添加到项目中。

<?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:layout_gravity="center"    android:background="@drawable/bg_dialog_layout"    android:orientation="vertical" >    <TextView        android:id="@+id/title"        style="@style/text_18_ffffff"        android:layout_width="match_parent"        android:layout_height="45dp"        android:background="@drawable/bg_dialog_top"        android:gravity="center"        android:text="提示"        android:visibility="visible" />    <ScrollView        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"        android:minHeight="120dp" >        <LinearLayout            android:id="@+id/content"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:minHeight="120dp"            android:background="@color/white"            android:gravity="center" >            <TextView                android:id="@+id/message"                style="@style/text_16_666666"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:gravity="left|center"                android:lineSpacingMultiplier="1.5"                android:minHeight="120dp"                android:paddingBottom="15dp"                android:paddingLeft="20dp"                android:paddingRight="20dp"                android:paddingTop="15dp" />        </LinearLayout>    </ScrollView>    <View        android:layout_width="match_parent"        android:layout_height="1.0px"        android:background="#ffd0d0d0" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="60dp"        android:layout_gravity="bottom"        android:gravity="center"        android:orientation="horizontal" >        <Button            android:id="@+id/negativeButton"            style="@style/text_15_666666_sdw"            android:layout_width="114dp"            android:layout_height="40dp"            android:layout_margin="10dp"            android:background="@drawable/bg_btn_negetive"            android:gravity="center"            android:text="取&#160;&#160;&#160;&#160;消" />        <Button            android:id="@+id/positiveButton"            style="@style/text_15_ffffff_sdw"            android:layout_width="114dp"            android:layout_height="40dp"            android:layout_margin="10dp"            android:background="@drawable/bg_btn_position"            android:gravity="center"            android:text="确&#160;&#160;&#160;&#160;定" />    </LinearLayout></LinearLayout>

调用示例:

public void showDialog() {        CustomDialog dialog = null;        CustomDialog.Builder builder = new CustomDialog.Builder(mContext);        builder.setTitle("应用更新");        builder.setMessage("当前是最新版本不需更新!");        builder.setPositiveButton("现在更新", new OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {                // TODO 处理点击确定的事件                dialog.dismiss();            }        });        builder.setNegativeButton("下次再说", new OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {                // TODO 处理点击取消的事件                dialog.dismiss();            }        });        //这里可以自定义一个布局文件,并将自定义的布局文件覆盖对话框的内容区域        // View view = getUpgradeContentView(bean);        // builder.setContentView(view);        // 设置点击back键dialog不消失        // builder.enableCloseOnBackKey(false);        dialog = builder.create();        dialog.setCloseOnTouchOutside(false);        dialog.show();    }

1.colors文件,这个颜色文件需要我们添加到values文件夹的colors.xml文件中

<?xml version="1.0" encoding="utf-8"?><resources><!-- 应用头部背景颜色 -->    <color name="bg_head">#e51c23</color>    <!-- 应用面板背景颜色 -->    <color name="bg_app_panel">#f5f0f5</color>    <color name="bg_app_content">#ffffff</color>    <!-- 应用中积极响应的按钮颜色色值 -->    <color name="bg_button_positive_nomal">#e51c23</color>    <color name="bg_button_positive_pressed">#a00303</color>    <color name="bg_button_positive_disenable">#999999</color>    <!-- 应用中按钮边框色值 -->    <color name="bg_button_stroke">#ffffff</color>    </resources>

2.dimens文件,添加到values文件夹中的dimens.xml中

<?xml version="1.0" encoding="utf-8"?><resources>    <!-- 应用text默认字体大小 -->    <dimen name="text_default_size">16sp</dimen>    <!-- 自定义对话框 -->    <dimen name="dialog_corner_size">10dp</dimen>    <dimen name="dialog_btn_corner_size">5dp</dimen></resources>

3.drable文件,进行dialog边框以及背景的设置

 1. bg_btn_negetive.xml 取消按钮的背景设置
<?xml version="1.0" encoding="UTF-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_pressed="true"><shape>            <solid android:color="@android:color/darker_gray" />            <corners android:radius="@dimen/dialog_btn_corner_size" />            <stroke android:width="1dp" android:color="@android:color/darker_gray" />        </shape></item>    <item android:state_enabled="true"><shape android:shape="rectangle">            <solid android:color="@android:color/white" />            <corners android:radius="@dimen/dialog_btn_corner_size" />            <stroke android:width="1dp" android:color="@android:color/darker_gray" />        </shape></item></selector>
 2. bg_btn_position.xml 确定按钮的背景设置
<?xml version="1.0" encoding="UTF-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <!-- 按钮被点击 -->    <item android:state_pressed="true"><shape>            <solid android:color="@color/bg_button_positive_pressed" />            <corners android:radius="@dimen/dialog_btn_corner_size" />            <stroke android:width="1dp" android:color="@color/bg_button_stroke" />        </shape></item>    <!-- 按钮可以点击 -->    <item android:state_enabled="true"><shape>            <solid android:color="@color/bg_button_positive_nomal" />            <corners android:radius="@dimen/dialog_btn_corner_size" />        </shape></item>    <!-- 按钮不可点击 -->    <item android:state_enabled="false"><shape>            <solid android:color="@android:color/darker_gray" />            <corners android:radius="@dimen/dialog_btn_corner_size" />        </shape></item></selector>
 3. bg_dialog_layout.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" >    <corners android:radius="@dimen/dialog_corner_size" />    <solid android:color="@color/bg_app_panel" /></shape>
 4. bg_dialog_bottom.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" >    <corners   android:bottomLeftRadius="@dimen/dialog_corner_size"android:bottomRightRadius="@dimen/dialog_corner_size" /></shape>
 5. bg_dialog_top.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" >    <corners      android:topLeftRadius="@dimen/dialog_corner_size"      android:topRightRadius="@dimen/dialog_corner_size"/>    <solid android:color="@color/bg_head" /></shape>
  1. styles文件,将以下style添加到styles.xml文件中
<style name="text_16_666666">        <item name="android:textSize">16.0dip</item>        <item name="android:textColor">#ff666666</item>    </style> <style name="text_15_666666_sdw" parent="@style/sdw_white">        <item name="android:textSize">15.0dip</item>        <item name="android:textColor">#ff666666</item>    </style> <style name="Dialog" parent="android:style/Theme.Dialog">        <item name="android:background">#00000000</item>        <item name="android:windowBackground">@android:color/transparent</item>        <item name="android:windowNoTitle">true</item>        <item name="android:windowIsFloating">true</item>    </style>

以上主要就是资源文件了,切记先把资源文件导入后在导入layout文件,最后才导入java代码。


谨以此文记录关于自定义Dialog的路程

0 0
原创粉丝点击