通过源码分析,修改AlertDialog按钮的颜色

对话框

弹出对话框对任何一个Android开发者都不是什么难事,代码也非常简单,简单的贴出来都觉得是个不光彩的事。

    public void showDialog(View v){
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setTitle("dialog");
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // .....
            }
        });
        builder.setNegativeButton("取消",null);
        builder.show();
    }

如果这是一个普通的AlertDialog教程,写到此处就大功告成了。问题是,公司产品经理感觉Dialog按钮的颜色不舒服,和绿帽子一样颜色,太不爽,想改成和顶部AppBar一个颜色。
我想了想,觉得因为一个Dialog跳槽走人也说不过去,只能拍拍胸脯说没问题。

众所周知,我们可以setView()定制不同界面样式的Dialog,随便你在布局中发挥

        AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setView(view);
        builder.show();

但是这种方法还要去搭建一个布局文件,太不爽。
紧接着我突然想到了,通过修改Dialog主题样式从而改变Dialog按钮的颜色。天才啊~
直接打开主题样式文件 values\styles.xml。

<resources>

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

当前程序采用的是AppCompat的主题,也是目前程序主流的主题。
然,并,卵!
如何修改Dialog样式了呢。上面的colorPrimary,colorAccent等分别控制什么的颜色呢。别着急,先看下面一张图:

主题颜色
  1. android:colorPrimaryDark 应用的主要暗色调,statusBarColor默认使用该颜色
  2. android:statusBarColor 状态栏颜色,默认使用colorPrimaryDark
  3. android:colorPrimary 应用的主要色调,actionBar默认使用该颜色
  4. android:windowBackground 窗口背景颜色
  5. android:navigationBarColor 底部栏颜色
  6. android:colorForeground 应用的前景色,ListView的分割线,switch滑动区默认使用该颜色
  7. android:colorBackground 应用的背景色,popMenu的背景默认使用该颜色
  8. android:colorAccent 一般控件的选种效果默认采用该颜色
  9. android:colorControlNormal 控件的默认色调
  10. android:colorControlHighlight 控件按压时的色调
  11. android:colorControlActivated 控件选中时的颜色,默认使用colorAccent
  12. android:colorButtonNormal 默认按钮的背景颜色
  13. android:textColor Button,textView的文字颜色
  14. android:textColorPrimaryDisableOnly RadioButton checkbox等控件的文字
  15. android:textColorPrimary 应用的主要文字颜色,actionBar的标题文字默认使用该颜色

上面加粗的就是创建项目默认带的,哇~ 原来主题可以控制这么多颜色啊。其实这还不是全部的啊。
问题回到主题,如何修改AlertDialog按钮的颜色啊。上面没有写着啊。不要怕,咱们去看看AlertDialog的源码。
AlertDialog是通过Builder创建的。

        public Builder(Context context) {
            this(context, resolveDialogTheme(context, 0));
        }

可以看到片Build创建的时候调用了resolveDialogTheme这个方法,英语好的一眼就知道这是解析主题的意思,点进去看看这个方法:

    static int resolveDialogTheme(Context context, int resid) {
        if (resid >= 0x01000000) {   // start of real resource IDs.
            return resid;
        } else {
            TypedValue outValue = new TypedValue();
            context.getTheme().resolveAttribute(R.attr.alertDialogTheme, outValue, true);
            return outValue.resourceId;
        }
    }

*** 核心是看这个:context.getTheme().resolveAttribute(R.attr.alertDialogTheme, outValue, true);***
这个话的意思就是上下文获取当前主题解析alertDialogTheme这个属性。
原来终于明白了,我们要想修改AlertDialog样式需要在主题中设置alertDialogTheme,这个属性。

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="alertDialogTheme">怎么写啊??</item>
    </style>

问题来了,alertDialogTheme这个又该怎么写呢。这次ctrl+左键点击Theme.AppCompat.Light.DarkActionBar进去看看默认的alertDialogTheme是怎么配置的,我们按照葫芦画瓢就可以了。
进来千万不要头晕,我们来缕缕:
首先

<style name="Theme.AppCompat.Light.DarkActionBar" parent="Base.Theme.AppCompat.Light.DarkActionBar"/>

继续翻家谱,点击父样式Base.Theme.AppCompat.Light.DarkActionBar

    <style name="Base.Theme.AppCompat.Light.DarkActionBar" parent="Base.Theme.AppCompat.Light">
        <item name="actionBarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
        <item name="actionBarWidgetTheme">@null</item>
        <item name="actionBarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>

        <!-- Panel attributes -->
        <item name="listChoiceBackgroundIndicator">@drawable/abc_list_selector_holo_dark</item>

        <item name="colorPrimaryDark">@color/primary_dark_material_dark</item>
        <item name="colorPrimary">@color/primary_material_dark</item>
    </style>

发现Base.Theme.AppCompat.Light.DarkActionBar还是没有我们想要的,继续点击Base.Theme.AppCompat.Light,继续往上翻

<style name="Base.Theme.AppCompat.Light" parent="Base.V7.Theme.AppCompat.Light"></style>

继续...

<style name="Base.V7.Theme.AppCompat.Light" parent="Platform.AppCompat.Light">
    ....
   <item name="alertDialogTheme">@style/Theme.AppCompat.Light.Dialog.Alert</item>
</style>

终于功夫不负有心人,找到了alertDialogTheme这个属性,看看它对应的是@style/Theme.AppCompat.Light.Dialog.Alert
我们把这个代码复制到我们的样式中,这就相当于你什么都没改:

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="alertDialogTheme">@style/Theme.AppCompat.Light.Dialog.Alert</item>
    </style>

于是乎我们开始自定义这个样式Theme.AppCompat.Light.Dialog.Alert

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="alertDialogTheme">@style/Theme.AppCompat.Light.Dialog.Alert.Self</item>
    </style>

    <style name="Theme.AppCompat.Light.Dialog.Alert.Self"
           parent="@style/Theme.AppCompat.Light.Dialog.Alert">
          <!--怎么写呢?-->
    </style>

怎么自定义呢,于是乎,又需要翻看Theme.AppCompat.Light.Dialog.Alert的源码了。过程和上面雷同,需要多翻几次,就不列举了。直接说结果,最终你会发现
Theme.AppCompat.Light.Dialog.Alert继承自Base.V7.Theme.AppCompat.Light

<style name="Base.V7.Theme.AppCompat.Light" parent="Platform.AppCompat.Light">
    ....
  
</style>

这个是不是很眼熟啊,没错,上面的代码曾经翻到过它。这时候如果你按照正常思维模式去查看哪个属性控制按钮颜色,你还需要翻看AlerDialog源码,我只能说有点麻烦了,很不爽的。
那怎么看呢?
介绍一个小技巧。
我们先看按钮默认的颜色。

按钮颜色

然后看Base.V7.Theme.AppCompat.Light样式下只有colorAccent 对应这个颜色。

按钮颜色

于是乎我们可以猜测,colorAccent 这个属性可能是控制按钮的颜色。于是乎赶快添加到自定义的样式中。填写和状态栏的一样的颜色:

    <style name="Theme.AppCompat.Light.Dialog.Alert.Self"
           parent="@style/Theme.AppCompat.Light.Dialog.Alert">
        <item name="colorAccent">#3F51B5</item>
    </style>

运行看看效果吧:

Paste_Image.png

哇~ 终于改成和状态栏一个颜色了。
把最终代码粘贴出来,仅仅是改了values/styles中的主题样式:

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!--自定义AlertDialog-->
        <item name="alertDialogTheme">@style/Theme.AppCompat.Light.Dialog.Alert.Self</item>
    </style>
    <style name="Theme.AppCompat.Light.Dialog.Alert.Self"
           parent="@style/Theme.AppCompat.Light.Dialog.Alert">
        <!--修改AlertDialog按钮的颜色-->
        <item name="colorAccent">#3F51B5</item>
    </style>
</resources>

虽然,过程很复杂,但是结果确很简单。开发是非常重视结果的,但学习的时候过程的体验还是必不可少的,通过学习这个分析过程,大家可以尝试修改其它控件默认的样式啦。
更多精彩请关注微信公众账号likeDev,公众账号名称:爱上Android。

likeDev.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容