• 自定义 Android 对话框 (AlertDialog) 的样式


    Android 提供了 AlertDialog 类可通过其内部类 Builder 轻松创建对话框窗口,但是没法对这个对话框窗口进行定制,为了修改 AlertDialog 窗口显示的外观,解决的办法就是创建一个指定的 AlertDialog 和 AlertDialog.Builder 类。

    定义外观
    我们希望将上面默认的对话框外观修改为如下图所示的新对话框风格:

    该对话框将支持下面特性:
        1.    可从资源或者字符串直接指定对话框标题
        2.    可从资源、字符串和自定义布局来设置对话框内容
        3.    可设置按钮和相应的事件处理
     编写布局、样式和主题
    该对话框使用一个定制的布局来输出内容,布局定义的id将用于访问标题 TextView,下面是定义文件:
    01
    <?xml version="1.0" encoding="utf-8"?>
    02
     
    03
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    04
        android:orientation="vertical"
    05
        android:layout_width="fill_parent"
    06
        android:minWidth="280dip"
    07
        android:layout_height="wrap_content">
    08
     
    09
     
    10
        <LinearLayout
    11
            android:orientation="vertical"
    12
            android:background="@drawable/header"
    13
            android:layout_width="fill_parent"
    14
            android:layout_height="wrap_content">
    15
     
    16
            <TextView
    17
                style="@style/DialogText.Title"
    18
     
    19
                android:id="@+id/title"
    20
                android:paddingRight="8dip"
    21
                android:paddingLeft="8dip"
    22
                android:background="@drawable/title"
    23
                android:layout_width="wrap_content"
    24
     
    25
                android:layout_height="wrap_content"/>
    26
     
    27
        </LinearLayout>
    28
     
    29
        <LinearLayout
    30
            android:id="@+id/content"
    31
            android:orientation="vertical"
    32
            android:background="@drawable/center"
    33
     
    34
            android:layout_width="fill_parent"
    35
            android:layout_height="wrap_content">
    36
     
    37
            <TextView
    38
                style="@style/DialogText"
    39
                android:id="@+id/message"
    40
                android:padding="5dip"
    41
     
    42
                android:layout_width="fill_parent"
    43
                android:layout_height="wrap_content"/>
    44
     
    45
        </LinearLayout>
    46
     
    47
        <LinearLayout
    48
            android:orientation="horizontal"
    49
            android:background="@drawable/footer"
    50
     
    51
            android:layout_width="fill_parent"
    52
            android:layout_height="wrap_content">
    53
     
    54
            <Button
    55
                android:id="@+id/positiveButton"
    56
                android:layout_marginTop="3dip"
    57
                android:layout_width="0dip"
    58
     
    59
                android:layout_weight="1"
    60
                android:layout_height="wrap_content"
    61
                android:singleLine="true"/>
    62
     
    63
            <Button
    64
                android:id="@+id/negativeButton"
    65
     
    66
                android:layout_marginTop="3dip"
    67
                android:layout_width="0dip"
    68
                android:layout_weight="1"
    69
                android:layout_height="wrap_content"
    70
                android:singleLine="true"/>
    71
     
    72
     
    73
        </LinearLayout>
    74
     
    75
    </LinearLayout>

    根节点 LinearLayout 的宽度设置为 fill_parent 而最小的宽度是 280dip ,因此对话框的宽度将始终为屏幕宽度的 87.5%
    自定义的主题用于声明对话框是浮动的,而且使用自定义的背景和标题视图:
    01
    <?xml version="1.0" encoding="utf-8"?>
    02
    <resources>
    03
     
    04
        <style name="Dialog" parent="android:style/Theme.Dialog">
    05
            <item name="android:windowBackground">@null</item>
    06
     
    07
            <item name="android:windowNoTitle">true</item>
    08
            <item name="android:windowIsFloating">true</item>
    09
        </style>
    10
     
    11
    </resources>
    接下来我们需要定义对话框的标题和消息的显示:
    01
    <?xml version="1.0" encoding="utf-8"?>
    02
    <resources>
    03
     
    04
        <style name="DialogText">
    05
            <item name="android:textColor">#FF000000</item>
    06
     
    07
            <item name="android:textSize">12sp</item>
    08
        </style>
    09
     
    10
        <style name="DialogText.Title">
    11
            <item name="android:textSize">16sp</item>
    12
     
    13
            <item name="android:textStyle">bold</item>
    14
        </style>
    15
     
    16
    </resources>

    编写对话框和 Builder 类
    最好我们要提供跟 AletDialog.Builder 类一样的方法:
    001
    package net.androgames.blog.sample.customdialog.dialog;
    002
     
    003
    import net.androgames.blog.sample.customdialog.R;
    004
    import android.app.Dialog;
    005
    import android.content.Context;
    006
    import android.content.DialogInterface;
    007
    import android.view.LayoutInflater;
    008
    import android.view.View;
    009
    import android.view.ViewGroup.LayoutParams;
    010
    import android.widget.Button;
    011
    import android.widget.LinearLayout;
    012
    import android.widget.TextView;
    013
     
    014
    /**
    015
     *
    016
     * Create custom Dialog windows for your application
    017
     * Custom dialogs rely on custom layouts wich allow you to
    018
     * create and use your own look & feel.
    019
     *
    020
     * Under GPL v3 : http://www.gnu.org/licenses/gpl-3.0.html
    021
     *
    022
     * @author antoine vianey
    023
     *
    024
     */
    025
    public class CustomDialog extends Dialog {
    026
     
    027
        public CustomDialog(Context context, int theme) {
    028
            super(context, theme);
    029
        }
    030
     
    031
        public CustomDialog(Context context) {
    032
            super(context);
    033
        }
    034
     
    035
        /**
    036
         * Helper class for creating a custom dialog
    037
         */
    038
        public static class Builder {
    039
     
    040
            private Context context;
    041
            private String title;
    042
            private String message;
    043
            private String positiveButtonText;
    044
            private String negativeButtonText;
    045
            private View contentView;
    046
     
    047
            private DialogInterface.OnClickListener
    048
                            positiveButtonClickListener,
    049
                            negativeButtonClickListener;
    050
     
    051
            public Builder(Context context) {
    052
                this.context = context;
    053
            }
    054
     
    055
            /**
    056
             * Set the Dialog message from String
    057
             * @param title
    058
             * @return
    059
             */
    060
            public Builder setMessage(String message) {
    061
                this.message = message;
    062
                return this;
    063
            }
    064
     
    065
            /**
    066
             * Set the Dialog message from resource
    067
             * @param title
    068
             * @return
    069
             */
    070
            public Builder setMessage(int message) {
    071
                this.message = (String) context.getText(message);
    072
                return this;
    073
            }
    074
     
    075
            /**
    076
             * Set the Dialog title from resource
    077
             * @param title
    078
             * @return
    079
             */
    080
            public Builder setTitle(int title) {
    081
                this.title = (String) context.getText(title);
    082
                return this;
    083
            }
    084
     
    085
            /**
    086
             * Set the Dialog title from String
    087
             * @param title
    088
             * @return
    089
             */
    090
            public Builder setTitle(String title) {
    091
                this.title = title;
    092
                return this;
    093
            }
    094
     
    095
            /**
    096
             * Set a custom content view for the Dialog.
    097
             * If a message is set, the contentView is not
    098
             * added to the Dialog...
    099
             * @param v
    100
             * @return
    101
             */
    102
            public Builder setContentView(View v) {
    103
                this.contentView = v;
    104
                return this;
    105
            }
    106
     
    107
            /**
    108
             * Set the positive button resource and it's listener
    109
             * @param positiveButtonText
    110
             * @param listener
    111
             * @return
    112
             */
    113
            public Builder setPositiveButton(int positiveButtonText,
    114
                    DialogInterface.OnClickListener listener) {
    115
                this.positiveButtonText = (String) context
    116
                        .getText(positiveButtonText);
    117
                this.positiveButtonClickListener = listener;
    118
                return this;
    119
            }
    120
     
    121
            /**
    122
             * Set the positive button text and it's listener
    123
             * @param positiveButtonText
    124
             * @param listener
    125
             * @return
    126
             */
    127
            public Builder setPositiveButton(String positiveButtonText,
    128
                    DialogInterface.OnClickListener listener) {
    129
                this.positiveButtonText = positiveButtonText;
    130
                this.positiveButtonClickListener = listener;
    131
                return this;
    132
            }
    133
     
    134
            /**
    135
             * Set the negative button resource and it's listener
    136
             * @param negativeButtonText
    137
             * @param listener
    138
             * @return
    139
             */
    140
            public Builder setNegativeButton(int negativeButtonText,
    141
                    DialogInterface.OnClickListener listener) {
    142
                this.negativeButtonText = (String) context
    143
                        .getText(negativeButtonText);
    144
                this.negativeButtonClickListener = listener;
    145
                return this;
    146
            }
    147
     
    148
            /**
    149
             * Set the negative button text and it's listener
    150
             * @param negativeButtonText
    151
             * @param listener
    152
             * @return
    153
             */
    154
            public Builder setNegativeButton(String negativeButtonText,
    155
                    DialogInterface.OnClickListener listener) {
    156
                this.negativeButtonText = negativeButtonText;
    157
                this.negativeButtonClickListener = listener;
    158
                return this;
    159
            }
    160
     
    161
            /**
    162
             * Create the custom dialog
    163
             */
    164
            public CustomDialog create() {
    165
                LayoutInflater inflater = (LayoutInflater) context
    166
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    167
                // instantiate the dialog with the custom Theme
    168
                final CustomDialog dialog = new CustomDialog(context,
    169
                        R.style.Dialog);
    170
                View layout = inflater.inflate(R.layout.dialog, null);
    171
                dialog.addContentView(layout, new LayoutParams(
    172
                        LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
    173
                // set the dialog title
    174
                ((TextView) layout.findViewById(R.id.title)).setText(title);
    175
                // set the confirm button
    176
                if (positiveButtonText != null) {
    177
                    ((Button) layout.findViewById(R.id.positiveButton))
    178
                            .setText(positiveButtonText);
    179
                    if (positiveButtonClickListener != null) {
    180
                        ((Button) layout.findViewById(R.id.positiveButton))
    181
                                .setOnClickListener(new View.OnClickListener() {
    182
                                    public void onClick(View v) {
    183
                                        positiveButtonClickListener.onClick(
    184
                                                dialog,
    185
                                                DialogInterface.BUTTON_POSITIVE);
    186
                                    }
    187
                                });
    188
                    }
    189
                } else {
    190
                    // if no confirm button just set the visibility to GONE
    191
                    layout.findViewById(R.id.positiveButton).setVisibility(
    192
                            View.GONE);
    193
                }
    194
                // set the cancel button
    195
                if (negativeButtonText != null) {
    196
                    ((Button) layout.findViewById(R.id.negativeButton))
    197
                            .setText(negativeButtonText);
    198
                    if (negativeButtonClickListener != null) {
    199
                        ((Button) layout.findViewById(R.id.negativeButton))
    200
                                .setOnClickListener(new View.OnClickListener() {
    201
                                    public void onClick(View v) {
    202
                                        positiveButtonClickListener.onClick(
    203
                                                dialog,
    204
                                                DialogInterface.BUTTON_NEGATIVE);
    205
                                    }
    206
                                });
    207
                    }
    208
                } else {
    209
                    // if no confirm button just set the visibility to GONE
    210
                    layout.findViewById(R.id.negativeButton).setVisibility(
    211
                            View.GONE);
    212
                }
    213
                // set the content message
    214
                if (message != null) {
    215
                    ((TextView) layout.findViewById(
    216
                            R.id.message)).setText(message);
    217
                } else if (contentView != null) {
    218
                    // if no message set
    219
                    // add the contentView to the dialog body
    220
                    ((LinearLayout) layout.findViewById(R.id.content))
    221
                            .removeAllViews();
    222
                    ((LinearLayout) layout.findViewById(R.id.content))
    223
                            .addView(contentView,
    224
                                    new LayoutParams(
    225
                                            LayoutParams.WRAP_CONTENT,
    226
                                            LayoutParams.WRAP_CONTENT));
    227
                }
    228
                dialog.setContentView(layout);
    229
                return dialog;
    230
            }
    231
     
    232
        }
    233
     
    234
    }

    使用自定义的 Builder
    使用方法很简单:
    01
    /**
    02
     * Build the desired Dialog
    03
     * CUSTOM or DEFAULT
    04
     */
    05
    @Override
    06
    public Dialog onCreateDialog(int dialogId) {
    07
        Dialog dialog = null;
    08
        switch (dialogId) {
    09
            case CUSTOM_DIALOG :
    10
                CustomDialog.Builder customBuilder = new
    11
                    CustomDialog.Builder(CustomDialogActivity.this);
    12
                customBuilder.setTitle("Custom title")
    13
                    .setMessage("Custom body")
    14
                    .setNegativeButton("Cancel",
    15
                            new DialogInterface.OnClickListener() {
    16
                        public void onClick(DialogInterface dialog, int which) {
    17
                            CustomDialogActivity.this
    18
                            .dismissDialog(CUSTOM_DIALOG);
    19
                        }
    20
                    })
    21
                    .setPositiveButton("Confirm",
    22
                            new DialogInterface.OnClickListener() {
    23
                        public void onClick(DialogInterface dialog, int which) {
    24
                            dialog.dismiss();
    25
                        }
    26
                    });
    27
                dialog = customBuilder.create();
    28
                break;
    29
            case DEFAULT_DIALOG :
    30
                AlertDialog.Builder alertBuilder = new
    31
                    AlertDialog.Builder(CustomDialogActivity.this);
    32
                alertBuilder.setTitle("Default title")
    33
                    .setMessage("Default body")
    34
                    .setNegativeButton("Cancel",
    35
                            new DialogInterface.OnClickListener() {
    36
                        public void onClick(DialogInterface dialog, int which) {
    37
                            dialog.dismiss();
    38
                        }
    39
                    })
    40
                    .setPositiveButton("Confirm",
    41
                            new DialogInterface.OnClickListener() {
    42
                        public void onClick(DialogInterface dialog, int which) {
    43
                            CustomDialogActivity.this
    44
                            .dismissDialog(DEFAULT_DIALOG);
    45
                        }
    46
                    });
    47
                dialog = alertBuilder.create();
    48
                break;
    49
        }
    50
        return dialog;
    51
    }

    完整的代码下载: SampleCustomDialog

  • 相关阅读:
    数据结构实现(四)二叉查找树java实现
    数据结构实现(三)二叉树
    git
    抓包原理
    数据结构实现(二)队列
    86. Partition List
    82. Remove Duplicates from Sorted List II
    83. Remove Duplicates from Sorted List
    排序算法总结
    上下文切换详解
  • 原文地址:https://www.cnblogs.com/jiezzy/p/2949768.html
Copyright © 2020-2023  润新知