zoukankan      html  css  js  c++  java
  • 自定义 Android 对话框 (AlertDialog) 的样式

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

    Android default Dialog

    定义外观

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

    Custom Android Dialog

    该对话框将支持下面特性:

    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

    Enjoy !

    http://blog.androgames.net/10/custom-android-dialog/

  • 相关阅读:
    弦图点染色问题
    BZOJ1098: [POI2007]办公楼biu
    BZOJ1097: [POI2007]旅游景点atr
    BZOJ1068: [SCOI2007]压缩
    BZOJ1055: [HAOI2008]玩具取名
    BZOJ4199: [Noi2015]品酒大会
    BZOJ2527: [Poi2011]Meteors
    BZOJ1493 [NOI2007]项链工厂
    BZOJ1095 ZJOI2007 Hide 捉迷藏
    bzoj1468 Tree
  • 原文地址:https://www.cnblogs.com/chiuschen/p/3155999.html
Copyright © 2011-2022 走看看