我的Android进阶之旅------>Android中Dialog系统样式讲解

今天在维护公司的一个APP的时候,有如下场景。

弹出一个AlertDialog的时候,在系统语言是中文的时候,如下所示:

弹出一个AlertDialog的时候,在系统语言是English的时候,如下所示:

可以发现在系统语言为英语的时候,对话框中的白色文字已经完全看不清楚,对话框的背景颜色也变成了白色。因此需要修改对话框的主题。

修改之前代码如下:

AlertDialog commedialog = new AlertDialog.Builder(
					WalkieTalkieActivity.this)
					.setTitle(title)
					.setView(vi_nolong)
					.setPositiveButton(
							WalkieTalkieActivity.this.getResources().getString(R.string.ok),
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog, int arg1) {

									int j = mSelectedGroupNum + 1;
									int power_last = mIntercomSharePrefs.getInt("CurrentPower_"+j,0);
									Log.i("wxj", "btn_power CurrentPower_"+j+" :" + power_last);
									if (power_last == 1) {
										mEditor.putInt("CurrentPower_"+j,0).commit();
										mIntercom.setPowerLevel(0);
										btn_power.setBackgroundResource(R.drawable.power_high);

									} else if (power_last == 0) {
										mEditor.putInt("CurrentPower_"+j,1).commit();
										mIntercom.setPowerLevel(1);
										btn_power.setBackgroundResource(R.drawable.power_low);
									}
									dialog.dismiss();
									((ViewGroup) vi_nolong.getParent()).removeView(vi_nolong);
								}
							})
					.setNegativeButton(
							WalkieTalkieActivity.this.getResources().getString(R.string.cancel),
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {

									dialog.dismiss();
									((ViewGroup) vi_nolong.getParent()).removeView(vi_nolong);
								}
							}).create();
			commedialog.setCanceledOnTouchOutside(false);
			commedialog.show();

可以发现,new AlertDialog.Builder的时候没有指定主题,

AlertDialog commedialog = new AlertDialog.Builder(WalkieTalkieActivity.this)

我们可以在new AlertDialog.Builder的时候指定一个主题,如下所示:

AlertDialog commedialog = new AlertDialog.Builder(
					WalkieTalkieActivity.this,AlertDialog.THEME_HOLO_DARK)

完整代码如下:

AlertDialog commedialog = new AlertDialog.Builder(
					WalkieTalkieActivity.this,AlertDialog.THEME_HOLO_DARK)
					.setTitle(title)
					.setView(vi_nolong)
					.setPositiveButton(
							WalkieTalkieActivity.this.getResources().getString(R.string.ok),
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog, int arg1) {

									int j = mSelectedGroupNum + 1;
									int power_last = mIntercomSharePrefs.getInt("CurrentPower_"+j,0);
									Log.i("wxj", "btn_power CurrentPower_"+j+" :" + power_last);
									if (power_last == 1) {
										mEditor.putInt("CurrentPower_"+j,0).commit();
										mIntercom.setPowerLevel(0);
										btn_power.setBackgroundResource(R.drawable.power_high);

									} else if (power_last == 0) {
										mEditor.putInt("CurrentPower_"+j,1).commit();
										mIntercom.setPowerLevel(1);
										btn_power.setBackgroundResource(R.drawable.power_low);
									}
									dialog.dismiss();
									((ViewGroup) vi_nolong.getParent()).removeView(vi_nolong);
								}
							})
					.setNegativeButton(
							WalkieTalkieActivity.this.getResources().getString(R.string.cancel),
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {

									dialog.dismiss();
									((ViewGroup) vi_nolong.getParent()).removeView(vi_nolong);
								}
							}).create();
			commedialog.setCanceledOnTouchOutside(false);
			commedialog.show();

这样的话就指定了一个黑色背景的主题,这样在系统语言为英语的时候,背景也是黑色的,如下所示:

在系统语言为中文的时候,背景也是黑色的,如下所示:

====================================================================================================================================

下面从源码角度来看看到底是怎么回事,查看AlertDialog.Build代码如下:

       /**
         * Constructor using a context for this builder and the {@link AlertDialog} it creates.
         */
        public Builder(Context context) {
            this(context, resolveDialogTheme(context, 0));
        }

        /**
         * Constructor using a context and theme for this builder and
         * the {@link AlertDialog} it creates.  The actual theme
         * that an AlertDialog uses is a private implementation, however you can
         * here supply either the name of an attribute in the theme from which
         * to get the dialog‘s style (such as {@link android.R.attr#alertDialogTheme}
         * or one of the constants
         * {@link AlertDialog#THEME_TRADITIONAL AlertDialog.THEME_TRADITIONAL},
         * {@link AlertDialog#THEME_HOLO_DARK AlertDialog.THEME_HOLO_DARK}, or
         * {@link AlertDialog#THEME_HOLO_LIGHT AlertDialog.THEME_HOLO_LIGHT}.
         */
        public Builder(Context context, int theme) {
            P = new AlertController.AlertParams(new ContextThemeWrapper(
                    context, resolveDialogTheme(context, theme)));
            mTheme = theme;
        }

resolveDialogTheme(Context context, int resid) 代码如下:

    static int resolveDialogTheme(Context context, int resid) {
        if (resid == THEME_TRADITIONAL) {
            return com.android.internal.R.style.Theme_Dialog_Alert;
        } else if (resid == THEME_HOLO_DARK) {
            return com.android.internal.R.style.Theme_Holo_Dialog_Alert;
        } else if (resid == THEME_HOLO_LIGHT) {
            return com.android.internal.R.style.Theme_Holo_Light_Dialog_Alert;
        } else if (resid == THEME_DEVICE_DEFAULT_DARK) {
            return com.android.internal.R.style.Theme_DeviceDefault_Dialog_Alert;
        } else if (resid == THEME_DEVICE_DEFAULT_LIGHT) {
            return com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog_Alert;
        } else if (resid >= 0x01000000) {   // start of real resource IDs.
            return resid;
        } else {
            TypedValue outValue = new TypedValue();
            context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogTheme,
                    outValue, true);
            return outValue.resourceId;
        }
    }

几个主题的值为:

 /**
     * Special theme constant for {@link #AlertDialog(Context, int)}: use
     * the traditional (pre-Holo) alert dialog theme.
     */
    public static final int THEME_TRADITIONAL = 1;

    /**
     * Special theme constant for {@link #AlertDialog(Context, int)}: use
     * the holographic alert theme with a dark background.
     */
    public static final int THEME_HOLO_DARK = 2;

    /**
     * Special theme constant for {@link #AlertDialog(Context, int)}: use
     * the holographic alert theme with a light background.
     */
    public static final int THEME_HOLO_LIGHT = 3;

    /**
     * Special theme constant for {@link #AlertDialog(Context, int)}: use
     * the device‘s default alert theme with a dark background.
     */
    public static final int THEME_DEVICE_DEFAULT_DARK = 4;

    /**
     * Special theme constant for {@link #AlertDialog(Context, int)}: use
     * the device‘s default alert theme with a dark background.
     */
    public static final int THEME_DEVICE_DEFAULT_LIGHT = 5;

由此可见,当我们不指定主题的时候,

AlertDialog commedialog = new AlertDialog.Builder(WalkieTalkieActivity.this) 

系统给我们的主题是:

 TypedValue outValue = new TypedValue();
            context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogTheme,
                    outValue, true);
            return outValue.resourceId;

====================================================================================================================================

下面分别来测试一下这几个主题

主题为:AlertDialog.THEME_HOLO_LIGHT

AlertDialog commedialog = new AlertDialog.Builder(
					WalkieTalkieActivity.this,AlertDialog.THEME_HOLO_LIGHT)

主题为:AlertDialog.THEME_TRADITIONAL

AlertDialog commedialog = new AlertDialog.Builder(
					WalkieTalkieActivity.this,AlertDialog.THEME_TRADITIONAL)

主题为:AlertDialog.THEME_DEVICE_DEFAULT_DARK

AlertDialog commedialog = new AlertDialog.Builder(
					WalkieTalkieActivity.this,AlertDialog.THEME_DEVICE_DEFAULT_DARK)

主题为:AlertDialog.THEME_DEVICE_DEFAULT_LIGHT

AlertDialog commedialog = new AlertDialog.Builder(
					WalkieTalkieActivity.this,AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)

====================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址:http://blog.csdn.net/ouyang_peng

====================================================================================

版权声明:本文为欧阳鹏原创文章,欢迎转载,转载请注明出处! http://blog.csdn.net/ouyang_peng

时间: 2025-01-05 15:36:05

我的Android进阶之旅------>Android中Dialog系统样式讲解的相关文章

我的Android进阶之旅------> Android在TextView中显示图片方法

面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包含图像的文本信息),并简要说明实现方法. 答案:Android SDK支持如下显示富文本信息的方式. 1.使用TextView组件可以显示富文本信息.在TextView组件中可以使用富文本标签来显示富文本信息,这种标签类似于HTML标签,但比HTML标签简单,支持有限的几种显示富文本的方式.如<font>标签用于设置字体和颜色,<b>用于设置粗体.包含这些标签的文本不能直接作为TextView.se

我的Android进阶之旅------&gt; Android为TextView组件中显示的文本添加背景色

通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article/details/46916963) 我们学会了在TextView中显示图片的方法,现在我们来学习如何为TextView组件中显示的文本添加背景色.要求完成的样子如图所示: 首先来学习使用BackgroundColorSpan对象设置文字背景色,代码如下: TextView textView=(TextV

我的Android进阶之旅------&gt;Android疯狂连连看游戏的实现之实现游戏逻辑(五)

在上一篇<我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)>中提到的两个类: GameConf:负责管理游戏的初始化设置信息. GameService:负责游戏的逻辑实现. 其中GameConf的代码如下:cn\oyp\link\utils\GameConf.java package cn.oyp.link.utils; import android.content.Context; /** * 保存游戏配置的对象

我的Android进阶之旅------&gt;Android利用Sensor(传感器)实现水平仪功能的小例

这里介绍的水平仪,指的是比较传统的气泡水平仪,在一个透明圆盘内充满液体,液体中留有一个气泡,当一端翘起时,该气泡就会浮向翘起的一端. 利用方向传感器返回的第一个参数,实现了一个指南针小应用. 我的Android进阶之旅------>Android利用Sensor(传感器)实现指南针功能 (地址:http://blog.csdn.net/ouyang_peng/article/details/8801204) 接下来,我们利用返回的第二.三个参数实现该水平仪.因为第二个参数,反映底部翘起的角度(当

我的Android进阶之旅------&gt;Android字符串资源中的单引号问题error: Apostrophe not preceded by 的解决办法

刚刚在string字符串资源文件中,写了一个单引号,报错了,错误代码如下 error: Apostrophe not preceded by \ (in OuyangPeng's blog ) 资源文件如下: <?xml version="1.0" encoding="utf-8"?> <resources> <string name="ouyang">OuyangPeng's blog </string

我的Android进阶之旅------&gt;Android中android:windowSoftInputMode的用法

面试题:如何在显示某个Activity时立即弹出软键盘? 答案:在AndroidManifest.xml文件中设置<activity>标签的android:windowSoftInputMode属性可以在显示Activity时立即弹出当前输入法的软键盘(不管是否有获得焦点的空间). 设置为:android:windowSoftInputMode="stateVisible|adjustPan"   代码如下: <activity android:name="

我的Android进阶之旅------&gt;Android中的布局优化 include、merge 、ViewStub

1.如何重用布局文件? 可以使用<include>标签引用其他的布局文件,并用android:id属性覆盖被引用布局文件中顶层节点的android:id属性值.代码如下: <!--引用mylayout.xml--> <include android:id="@+id/layout1" layout="@layout/mylayout"/> 2.减少视图层级<merge /> 无论布局文件的根节点是什么,系统都会在上一层

我的Android进阶之旅------&gt;Android二级ListView列表的实现

实现如下图所示的二级列表效果 首先是在布局文件中,布局两个ListView,代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height=&

我的Android进阶之旅------&gt;Android使用AlarmManager全局定时器实现定时更换壁纸

该DEMO将会通过AlarmManager来周期的调用ChangeService,从而让系统实现定时更换壁纸的功能. 更换壁纸的API为android.app.WallpaperManager,它提供了clear()方法来清除壁纸,还提供了如下方法来设置壁纸. setResource(int resid)将壁纸设置为resid资源所代表的图片 setBitmap(Bitmap bitmap)将壁纸设置为bitmap所代表的位图 setStream(InputStream data)将壁纸设置为d