【Android UI】Android 颜色的表示和获取使用指南

在 Android 开发中,颜色的表示和获取方式非常多样,涵盖了从底层十六进制代码到高层主题属性引用的各个层面,以下是 Android 中关于颜色表示的完整指南。

1. 十六进制颜色值 (Hex Color Codes)

这是 Android 中颜色的底层表达方式。颜色由 Alpha (透明度)Red (红)Green (绿)Blue (蓝) 通道组成。

格式: #AARRGGBB (最常用) 或 #RRGGBB (默认不透明)。

组成:

  • AA: 透明度 (00=全透明, FF=不透明)。
  • RR: 红色值。
  • GG: 绿色值。
  • BB: 蓝色值。

示例:

  • #FF000000 (不透明黑色)
  • #80FF0000 (半透明红色 - 50%透明度)
  • #FFFFFF (白色,隐含 FF 透明度)

透明度参照表:

00%=FF(不透明)

5%=F2

10%=E5

15%=D8

20%=CC

25%=BF

30%=B2

35%=A5

40%=99

45%=8c

50%=7F

55%=72

60%=66

65%=59

70%=4c

75%=3F

80%=33

85%=21

90%=19

95%=0c

100%=00(全透明)

2. 在 XML 资源中定义颜色 (Color Definition)

为了方便管理和复用,通常会在 res/values/colors.xml 文件中定义颜色。

文件路径: res/values/colors.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 定义一个不透明颜色 -->
    <color name="colorPrimary">#6200EE</color>
    
    <!-- 定义带透明度的颜色 -->
    <color name="black_overlay">#66000000</color>
    
    <!-- 引用其他颜色 -->
    <color name="theme_default">@color/colorPrimary</color>

	<!-- 引用 Android 中颜色:transparent是透明色  -->
	<color name="transparent_default">@android:color/transparent</color>
	<color name="white_default">@android:color/white</color>

</resources>

3. 在 XML 布局中使用颜色

在布局文件(如 activity_main.xml)或样式文件(styles.xml)中引用颜色。

A. 引用资源颜色 (推荐)

这是最标准的做法,支持日夜间模式切换。

xml 复制代码
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/colorPrimary" />
B. 直接使用 Hex 值 (硬编码,不推荐)

仅用于临时测试,不建议在正式代码中使用。

xml 复制代码
<View
    android:background="#FF0000" ... />
C. 引用主题属性 (Attribute References)

这是 Material Design 和现代 Android 开发的核心。你不直接引用具体颜色,而是引用"当前主题下的某个语义颜色"。这是实现深色模式 (Dark Mode) 的关键。

语法: ?attr/属性名?android:attr/属性名

xml 复制代码
<TextView
    <!-- 使用当前主题定义的 "colorPrimary" 颜色 -->
    android:textColor="?attr/colorPrimary"
    <!-- 使用当前主题定义的背景色 -->
    android:background="?android:attr/colorBackground" />
  • ?android:attr/... :引用的是 Android 操作系统原生 的属性。
  • ?attr/... :引用的是 App 项目自身或第三方库(如 AppCompat / Material Design 库) 定义的属性。
特性 ?android:attr/colorControlNormal ?attr/colorControlNormal
全称 Android System Attribute Application/Library Attribute
定义位置 Android SDK 源代码中 (framework) AppCompat / Material 库中 (values/attrs.xml)
引入版本 API 21 (Android 5.0) AppCompat 库引入时(支持旧版本)
兼容性 。如果在 API 21 以下的手机运行,会崩溃或找不到资源。 。AppCompat 库通过"垫片"机制,让它在低版本(如 API 19)上也能工作。
命名空间 显式指定 android: 命名空间 隐式使用当前 App (通常是 res-auto)

对于颜色、样式属性(尤其是 Material Design 相关的):
永远优先去掉 android: 前缀 。用 ?attr/colorPrimary?attr/colorControlNormal。让 AndroidX 库帮你处理兼容性问题。

对于系统底层通用属性(很老的属性):

如果 IDE 提示找不到不带前缀的属性,或者你知道这是一个非常基础的属性(如 ?android:attr/selectableItemBackground?android:attr/listDivider),则使用 android: 前缀。

简单记忆:

只要是关于 主题色 (Primary/Secondary)控件着色 (Control) 的,统统不要android:

4. 颜色状态列表 (Color State List / Selector)

ColorStateList 是 Android 中一个非常重要的概念,它本质上不是一个单一的颜色,而是一组颜色的集合。它根据 View 的当前状态(按下、聚焦、禁用、选中等)返回不同的颜色值。

A. 什么是 ColorStateList

通常在 XML 中定义(即 <selector>),用于 View 在不同状态(按下、选中、禁用等)下显示不同颜色的情况。

文件路径: res/color/button_text_color.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 按下状态显示红色 -->
    <item android:color="#FF0000" android:state_pressed="true"/>
    
    <!-- 禁用状态显示灰色 -->
    <item android:color="#808080" android:state_enabled="false"/>
    
    <!-- 默认状态显示黑色 -->
    <item android:color="#000000"/>
</selector>

使用方式:

像普通颜色一样引用它:

xml 复制代码
<Button
    android:textColor="@color/button_text_color" ... />
B. Color (int) 转 ColorStateList

当你有一个单一的颜色值(int),但某个 API(如 TextView.setTextColor(ColorStateList))需要 ColorStateList 参数时,可以使用以下方式转换。这也意味着无论 View 处于什么状态,都显示同一个颜色。

Java / Kotlin:

java 复制代码
int myColor = Color.RED;
// int myColor = context.getColor(R.color.my_color)

// 转换方法
ColorStateList csl = ColorStateList.valueOf(myColor);

// 使用
textView.setTextColor(csl);
C. ColorStateList 转 Color (int)

注意: 不能直接把 ColorStateList 变成一个通用的颜色,因为必须指定"状态"才能知道取哪个颜色。

通常我们需要获取当前状态下的颜色

java 复制代码
ColorStateList csl = ContextCompat.getColorStateList(context, R.color.my_selector);

// 获取 View 的当前状态数组 (例如一个 Button)
int[] state = button.getDrawableState(); 

// 参数2:如果找不到匹配状态,返回的默认颜色
int colorForCurrentState = csl.getColorForState(state, Color.BLACK); 

// 或者手动指定获取 "按下" 状态的颜色
int colorPressed = csl.getColorForState(new int[]{android.R.attr.state_pressed}, Color.BLACK);
D. 在代码中动态创建 ColorStateList (复杂,不常用)

如果不想用 XML,可以用代码构造,但比较繁琐:

java 复制代码
int[][] states = new int[][] {
    new int[] { android.R.attr.state_enabled }, // enabled
    new int[] { -android.R.attr.state_enabled }, // disabled
    new int[] {} // default
};

int[] colors = new int[] {
    Color.BLACK,
    Color.GRAY,
    Color.BLACK
};

ColorStateList csl = new ColorStateList(states, colors);

5. 在 Java/Kotlin 代码中获取颜色

在代码中,颜色通常以 int 类型表示(不要混淆 Resource IDColor Int)。

A. 获取资源中的颜色 (标准方式)

使用 ContextCompat (推荐,兼容性最好):

java 复制代码
// Java/Kotlin
int color = ContextCompat.getColor(context, R.color.colorPrimary);

原生方式 (Android M/API 23+):

kotlin 复制代码
val color = context.getColor(R.color.colorPrimary)

过时方式 (Deprecated, 尽量避免):

java 复制代码
// 在旧版本中常用,现在已弃用,因为它无法正确处理主题
int color = getResources().getColor(R.color.colorPrimary); 
B. 解析 Hex 字符串

如果你从服务器获取了一个颜色代码字符串(如 "#FF0000"):

java 复制代码
// Java/Kotlin
import android.graphics.Color;

try {
    int color = Color.parseColor("#FF0000");
    view.setBackgroundColor(color);
} catch (IllegalArgumentException e) {
    // 处理格式错误
}
C. 使用 Color 类常量

Android Color 类提供了一些预定义的静态常量:

java 复制代码
view.setBackgroundColor(Color.RED);
// 透明色
view.setBackgroundColor(Color.TRANSPARENT);
D. 动态构建颜色 (ARGB)

如果你需要动态计算颜色(例如根据滑动进度改变透明度):

java 复制代码
// Java: Color.argb(alpha, red, green, blue) - 范围 0-255
int customColor = Color.argb(255, 100, 200, 50);

// Kotlin 扩展 (Android KTX)
val color = Color.valueOf(1.0f, 0.5f, 0.3f) // 范围 0.0-1.0 (API 26+)
E. 获取主题属性颜色 (Theme Attribute)

在代码中获取 ?attr/colorPrimary 这种动态颜色比较麻烦,需要解析主题:

java 复制代码
// java
public static int getThemeColor(Context context, int attrId) {
    TypedValue typedValue = new TypedValue();
    Theme theme = context.getTheme();
    // resolveAttribute 返回 true 表示找到了该属性
    if (theme.resolveAttribute(attrId, typedValue, true)) {
        return typedValue.data;
    }
    // 如果找不到,返回一个默认颜色(例如红色报错)
    return Color.RED; 
}

// 使用
// 获取 textColorPrimary (Android 系统自带属性)
int textPrimary = getThemeColor(this, android.R.attr.textColorPrimary);
// 设置给 View
textView.setTextColor(textPrimary );
kotlin 复制代码
// Kotlin 扩展函数示例
fun Context.getThemeColor(attrId: Int): Int {
    val typedValue = TypedValue()
    theme.resolveAttribute(attrId, typedValue, true)
    return typedValue.data
}

// 使用
val primaryColor = context.getThemeColor(com.google.android.material.R.attr.colorPrimary)

SettingsLib 中有工具类获取主题颜色值,可以参考:

java 复制代码
//SettingsLib/src/com/android/settingslib/Utils.java

@ColorInt
public static int getColorAttrDefaultColor(Context context, int attr) {
    TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
    @ColorInt int colorAccent = ta.getColor(0, 0);
    ta.recycle();
    return colorAccent;
}

public static ColorStateList getColorAttr(Context context, int attr) {
    TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
    ColorStateList stateList = null;
    try {
        stateList = ta.getColorStateList(0);
    } finally {
        ta.recycle();
    }
    return stateList;
}

6. 颜色类型对照表

方式 语法/代码示例 适用场景
Hex 码 #FF0000, #80FFFFFF 这里定义,UI设计稿对照
XML 定义 <color name="red">#FF0000</color> colors.xml 统一管理
XML 引用 @color/red 布局文件常规使用
主题引用 ?attr/colorPrimary 推荐,支持深色模式和换肤
状态列表 res/color/selector.xml 按钮点击、文字禁用态
代码获取 ContextCompat.getColor(...) 逻辑中需要设置颜色
代码解析 Color.parseColor("#...") 处理服务端下发颜色

7. 主题中常用的属性颜色值和含义

styles.xmlthemes.xml 中,以及布局引用(?attr/...)时,以下是最常用的语义化颜色属性。

A. 品牌/结构颜色 (Material Design)
属性名 (attr) 含义 典型用途
colorPrimary 主色调 App 的品牌色,用于 Toolbar、按钮背景等。
colorSecondary 次色调 强调色,用于 FAB 按钮、Switch 开关激活态、进度条等。
colorBackground 窗口背景色 Activity 的默认底色(浅色模式白,深色模式黑)。
colorSurface 表面色 CardView、BottomSheet、菜单的背景色。
B. 文本颜色 (Framework)
属性名 (android:attr) 含义 典型用途
textColorPrimary 主要文本色 标题、正文,最醒目的文字(深色模式下自动变浅)。
textColorSecondary 次要文本色 副标题、描述性文字,透明度较低。
textColorHint 提示文本色 EditText 的 hint 颜色。
C. 控件交互颜色 (Control)

这是自定义控件时最需要关注的系统属性:

属性名 (attr) 含义 典型用途
colorControlNormal 默认状态色 图标默认颜色、CheckBox 未选中时的边框色、EditText 未聚焦时的下划线。
colorControlActivated 激活状态色 CheckBox 选中时的颜色、EditText 聚焦时的下划线/光标(通常等于 colorSecondary 或 colorPrimary)。
colorControlHighlight 高亮/波纹色 按钮点击时的水波纹效果 (Ripple) 颜色。

8. ContextCompat 和 Context 的区别

  • Context : 是 Android 系统核心抽象类(环境上下文)。随着 Android 版本升级(API 21, 23, 26...),Context 类的方法签名和行为发生了变化。直接使用 Context 的某些方法可能会导致在旧手机上崩溃。
  • ContextCompat : 是 AndroidX (以前的 Support Library) 提供的一个帮助类(Helper Class)。它的作用是屏蔽系统版本的差异,提供统一的 API 接口。
A. 为什么要有 ContextCompat?

以获取颜色为例:

Android 6.0 (API 23) 之前: context.getResources().getColor(R.color.red)

Android 6.0 (API 23) 及之后: Google 废弃了上面的方法,引入了 context.getColor(R.color.red)(为了更好地支持主题化)。

如果你直接写代码:

java 复制代码
// 如果你在 API 21 的手机上运行这段代码(调用了 API 23 才有的方法),APP 会直接 Crash
context.getColor(R.color.red); 

如果你使用 ContextCompat:

java 复制代码
// ContextCompat 内部会自动判断当前手机系统版本
// if (SDK >= 23) call context.getColor()
// else call resources.getColor()
ContextCompat.getColor(context, R.color.red);
B. 使用场景总结

凡是涉及到获取资源(颜色、图片)或者系统权限 相关的操作,闭着眼睛使用 ContextCompat,它是最稳妥的方案。

场景 推荐使用 原因
获取资源 (Color, Drawable) ContextCompat 强烈推荐。防止 API 版本兼容性崩溃,且解决旧方法 Deprecated 警告。
检查权限 ContextCompat checkSelfPermission 在旧版本处理方式不同,兼容库帮你处理了。
启动 Activity/Service Context 核心功能,直接用 Context 即可。
获取系统服务 ContextCompat ContextCompat.getSystemService 某些情况下更安全,但通常直接用 Context 也没问题。
相关推荐
louisgeek2 小时前
Android Charles Proxy 抓包
android
恶猫3 小时前
SEELEN UI 桌面自定义工具 v2.3 介绍及安装教程, 深度美化win10/11,装机必备!!
ui·win11·win10·系统优化·桌面·桌面美化·桌面自定义
Exploring3 小时前
从零搭建使用 Open-AutoGML 搜索附近的美食
android·人工智能
ask_baidu4 小时前
Doris笔记
android·笔记
lc9991024 小时前
简洁高效的相机预览
android·linux
hqk5 小时前
鸿蒙ArkUI:状态管理、应用结构、路由全解析
android·前端·harmonyos
消失的旧时光-19435 小时前
从 C 链表到 Android Looper:MessageQueue 的底层原理一条线讲透
android·数据结构·链表
方白羽5 小时前
Android 中Flags从源码到实践
android·app·客户端
深蓝电商API5 小时前
从数据采集到商业变现:网络爬虫技术的实战与边界
android·爬虫