
本文详细讲解如何在 mainactivity 中创建并动态修改 gradientdrawable 对象,实现交通灯(红→黄→绿→红…)的循环颜色切换,涵盖兼容性处理、状态追踪与安全的颜色获取方式。
本文详细讲解如何在 mainactivity 中创建并动态修改 gradientdrawable 对象,实现交通灯(红→黄→绿→红…)的循环颜色切换,涵盖兼容性处理、状态追踪与安全的颜色获取方式。
在 Android 开发中,使用 GradientDrawable 是实现简单纯色圆形 UI 元素(如交通灯)的轻量级方案。关键在于:正确初始化、安全获取当前颜色、适配 API 差异,并维护状态以支持逻辑流转。
首先,在 onCreate() 中创建初始圆形 Drawable 并设置为 TextView(或 View)背景:
GradientDrawable drawable = new GradientDrawable(); drawable.setShape(GradientDrawable.OVAL); drawable.setColor(ContextCompat.getColor(this, R.color.red)); // ✅ 兼容低版本 light.setBackground(drawable);
⚠️ 注意:不要使用已弃用的 getResources().getColor() —— 从 Android 6.0(API 23)起该方法被标记为过时,推荐统一使用 ContextCompat.getColor(context, R.color.xxx) 保障向后兼容。
接下来,为按钮设置点击监听器。难点在于:GradientDrawable.getColor() 在 Android 7.0+ 返回 ColorStateList,需调用 .getDefaultColor() 获取实际颜色;而低版本则直接返回 int。因此必须进行 API 版本判断:
change.setOnClickListener(v -> {
GradientDrawable drawable = (GradientDrawable) light.getBackground();
int currentColor = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && drawable.getColor() != null) {
currentColor = drawable.getColor().getDefaultColor();
} else if (drawable.getColor() instanceof Integer) {
currentColor = (int) drawable.getColor();
}
int red = ContextCompat.getColor(this, R.color.red);
int yellow = ContextCompat.getColor(this, R.color.yellow);
int green = ContextCompat.getColor(this, R.color.green);
// 实现红 → 黄 → 绿 → 红 的循环逻辑(需记录上一状态)
if (currentColor == red) {
drawable.setColor(yellow);
} else if (currentColor == yellow) {
// 判断上一状态决定下一步:红→黄→绿,绿→黄→红
if (previousColor == red) {
drawable.setColor(green);
} else if (previousColor == green) {
drawable.setColor(red);
}
} else if (currentColor == green) {
drawable.setColor(yellow);
}
light.setBackground(drawable);
previousColor = currentColor; // 更新历史状态
});
? 核心要点总结:
- previousColor 是实现三色循环的关键状态变量,仅靠当前色无法区分“黄”是来自红还是绿;
- 始终使用 ContextCompat.getColor() 替代已废弃的 getResources().getColor();
- GradientDrawable.getColor() 在 API 24+ 返回 ColorStateList,务必通过 .getDefaultColor() 提取;
- 设置新颜色后,无需重复调用 setBackground()(setColor() 会自动触发重绘),但为明确性和兼容性,保留亦可;
- 若项目已启用 AndroidX,确保 colors.xml 中定义了 red、yellow、green 色值(如 #FF5722、#FFC107、#4CAF50)。
通过以上结构化实现,即可稳定、可维护地完成交通灯 UI 的交互逻辑,兼顾现代 API 特性与旧设备兼容性。











