Android ColorStateList 详解

QuibblerQuibbler 2021-12-27 约 18 分钟 157 次阅读

Android ColorStateList 详解

1、ColorStateList 概述

ColorStateList 是 Android 中用于管理不同状态下颜色的类,它允许为 View 的不同状态(如按下、聚焦、禁用等)设置不同的颜色。ColorStateList 广泛应用于按钮、文本框等控件的颜色管理,是实现响应式 UI 的重要工具。

核心特性:

        - 支持多种 View 状态的颜色定义

        - 可以通过 XML 或代码创建

        - 与 View 的状态变化自动同步

        - 支持过渡动画效果

        - 提高 UI 一致性和可维护性

应用场景:

        - 按钮的不同状态颜色

        - 文本的选中和未选中状态

        - 列表项的聚焦和点击状态

        - 任何需要根据状态变化颜色的控件

2、核心概念

2.1、View 状态

ColorStateList 支持的 View 状态包括:

        - android:state_pressed:按下状态

        - android:state_focused:聚焦状态

        - android:state_hovered:悬停状态

        - android:state_selected:选中状态

        - android:state_checkable:可勾选状态

        - android:state_checked:已勾选状态

        - android:state_enabled:启用状态

        - android:state_window_focused:窗口聚焦状态

2.2、ColorStateList 结构

ColorStateList 由一系列状态颜色对组成,每个状态颜色对包含:

- 状态数组:定义触发该颜色的状态组合

- 颜色值:对应状态下的颜色

2.3、状态匹配规则

- 状态数组为空:默认状态,适用于所有状态

- 状态数组包含多个状态:需要同时满足所有状态

- 状态数组中的状态可以取反(在状态名前加 -)

- 匹配优先级:更具体的状态组合优先级更高

3、XML 实现方式

3.1、创建 ColorStateList 文件

在 res/color/ 目录下创建 XML 文件:

<!-- res/color/button_background.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 按下状态 -->
    <item android:state_pressed="true"
          android:color="#FF4081" />
    <!-- 聚焦状态 -->
    <item android:state_focused="true"
          android:color="#3F51B5" />
    <!-- 禁用状态 -->
    <item android:state_enabled="false"
          android:color="#BDBDBD" />
    <!-- 默认状态 -->
    <item android:color="#2196F3" />
</selector>

3.2、应用 ColorStateList

在布局文件中引用:

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button"
    android:backgroundTint="@color/button_background" />

或者在 TextView 中使用:

<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Text"
    android:textColor="@color/text_color" />

3.3、复杂状态组合

<!-- 复杂状态组合 -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 按下且选中状态 -->
    <item android:state_pressed="true"
          android:state_selected="true"
          android:color="#FF5722" />
    <!-- 仅按下状态 -->
    <item android:state_pressed="true"
          android:color="#FF4081" />
    <!-- 仅选中状态 -->
    <item android:state_selected="true"
          android:color="#3F51B5" />
    <!-- 默认状态 -->
    <item android:color="#2196F3" />
</selector>

4、代码实现方式

4.1、创建 ColorStateList

// 使用 ColorStateList.Builder 创建
ColorStateList colorStateList = new ColorStateList.Builder()
    // 按下状态
    .addState(new int[]{android.R.attr.state_pressed},
              ContextCompat.getColor(context, R.color.pressed_color))
    // 聚焦状态
    .addState(new int[]{android.R.attr.state_focused},
              ContextCompat.getColor(context, R.color.focused_color))
    // 禁用状态
    .addState(new int[]{-android.R.attr.state_enabled},
              ContextCompat.getColor(context, R.color.disabled_color))
    // 默认状态
    .addState(new int[]{},
              ContextCompat.getColor(context, R.color.default_color))
    .build();

    // 或者从资源文件加载
ColorStateList colorStateList = ContextCompat.getColorStateList(context, R.color.button_background);

4.2、应用 ColorStateList

// 设置按钮背景色
button.setBackgroundTintList(colorStateList);

// 设置文本颜色
textView.setTextColor(colorStateList);

// 设置图标颜色
drawable.setTintList(colorStateList);

4.3、动态修改 ColorStateList

// 复制现有 ColorStateList 并修改
ColorStateList original = ContextCompat.getColorStateList(context, R.color.original);
int[][] states = original.getStates();
int[] colors = original.getColors();

// 修改颜色
colors[0] = ContextCompat.getColor(context, R.color.new_pressed);

// 创建新的 ColorStateList
ColorStateList modified = new ColorStateList(states, colors);

5、高级用法

5.1、状态过渡动画

从 Android 5.0 (API 21) 开始,ColorStateList 支持状态过渡动画:

<!-- 带过渡动画的 ColorStateList -->
<selector xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          tools:targetApi="lollipop">
    
    <item android:state_pressed="true"
          android:color="#FF4081" />
    <item android:color="#2196F3" />
</selector>

5.2、Theme 支持

在 Theme 中定义 ColorStateList:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorButtonNormal">@color/button_background</item>
    <item name="colorControlNormal">@color/control_normal</item>
    <item name="colorControlActivated">@color/control_activated</item>
    <item name="colorControlHighlight">@color/control_highlight</item>
</style>

5.3、Vector Drawable 配合使用

// 加载 Vector Drawable
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.ic_arrow);

// 设置 ColorStateList
drawable.setTintList(colorStateList);

// 应用到 ImageView
imageView.setImageDrawable(drawable);

5.4、自定义 View 中使用

public class CustomButton extends AppCompatButton {
    public CustomButton(Context context) {
        super(context);
        init();
    }
    
    private void init() {
        // 创建 ColorStateList
        ColorStateList colorStateList = new ColorStateList.Builder()
            .addState(new int[]{android.R.attr.state_pressed},
                      ContextCompat.getColor(getContext(), R.color.pressed))
            .addState(new int[]{},
                      ContextCompat.getColor(getContext(), R.color.normal))
            .build();
        
        // 设置背景色
        setBackgroundTintList(colorStateList);
    }
}

6、最佳实践与注意事项

6.1、性能优化

- 重用 ColorStateList 实例,避免频繁创建

- 使用 XML 定义复杂的 ColorStateList

- 避免在 onDraw() 等频繁调用的方法中创建 ColorStateList

- 合理设置状态顺序,提高匹配效率

6.2、兼容性处理

- 使用 ContextCompat.getColorStateList() 确保兼容性

- 对于旧版本 Android,手动处理状态变化

- 测试不同 Android 版本的表现

- 考虑不同屏幕密度的显示效果

6.3、常见问题

问题1:状态不生效

解决:检查状态顺序,更具体的状态应放在前面

问题2:颜色过渡不流畅

解决:确保使用 Android 5.0+ 或手动实现过渡动画

问题3:XML 中颜色值格式错误

解决:使用 #RRGGBB 或 #AARRGGBB 格式

6.4、总结

ColorStateList 是 Android 中管理 View 状态颜色的重要工具,通过合理使用 ColorStateList,可以为应用创建更加生动、响应式的用户界面。无论是通过 XML 还是代码创建,ColorStateList 都能帮助开发者轻松实现不同状态下的颜色变化。

关键要点:

        - 状态顺序很重要,具体状态在前

        - 支持复杂的状态组合

        - 从 API 21 开始支持过渡动画

        - 合理重用 ColorStateList 实例

        - 结合 Theme 和 Vector Drawable 使用

掌握 ColorStateList 的使用,对于创建美观、交互友好的 Android 应用至关重要,是 UI 开发中的基础技能之一。

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w