Android Kotlin:如何获取不同主题中定义为属性的颜色
解决方案
1. 确认自定义属性配置(回顾)
先确保你已在res/values/attrs.xml中定义自定义属性,并在三个主题中分别赋值:
<!-- attrs.xml --> <resources> <attr name="fabBackgroundColor" format="color" /> </resources> <!-- light主题(res/values/styles.xml) --> <style name="AppTheme.Light" parent="Theme.MaterialComponents.Light.NoActionBar"> <item name="fabBackgroundColor">#2196F3</item> </style> <!-- dark主题(res/values-night/styles.xml) --> <style name="AppTheme.Dark" parent="Theme.MaterialComponents.Dark.NoActionBar"> <item name="fabBackgroundColor">#FFC107</item> </style> <!-- plain主题(res/values/styles.xml) --> <style name="AppTheme.Plain" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <item name="fabBackgroundColor">#4CAF50</item> </style>
2. 在Activity中获取主题属性颜色并设置给FAB
核心是通过TypedValue获取当前主题的属性值,封装工具方法减少样板代码,注意Material FAB需用backgroundTintList而非直接设置背景色(避免破坏FAB默认样式):
Kotlin 实现
import android.content.Context import android.util.TypedValue import com.google.android.material.floatingactionbutton.FloatingActionButton import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.content.res.ColorStateList class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val fab = findViewById<FloatingActionButton>(R.id.fab) val fabColor = getThemeColor(R.attr.fabBackgroundColor) fab.backgroundTintList = ColorStateList.valueOf(fabColor) } // 复用性工具方法:获取当前主题对应属性的颜色值 private fun Context.getThemeColor(attrResId: Int): Int { val typedValue = TypedValue() theme.resolveAttribute(attrResId, typedValue, true) return typedValue.data } }
Java 实现
import android.content.Context; import android.util.TypedValue; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import com.google.android.material.floatingactionbutton.FloatingActionButton; import android.content.res.ColorStateList; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FloatingActionButton fab = findViewById(R.id.fab); int fabColor = getThemeColor(R.attr.fabBackgroundColor); fab.setBackgroundTintList(ColorStateList.valueOf(fabColor)); } // 复用性工具方法:获取当前主题对应属性的颜色值 private int getThemeColor(int attrResId) { TypedValue typedValue = new TypedValue(); getTheme().resolveAttribute(attrResId, typedValue, true); return typedValue.data; } }
3. 动态主题切换后的更新
如果App支持动态切换主题,在主题切换后(比如onResume或主题切换回调中)重新执行颜色设置逻辑即可:
override fun onResume() { super.onResume() val fab = findViewById<FloatingActionButton>(R.id.fab) fab.backgroundTintList = ColorStateList.valueOf(getThemeColor(R.attr.fabBackgroundColor)) }
关键注意点
- 必须用
backgroundTintList:Material FAB的背景样式(阴影、圆角)依赖该属性控制,直接调用setBackgroundColor会破坏默认UI效果。 - 工具方法简化代码:封装后的
getThemeColor避免了重复编写TypedArray相关样板代码,只需传入属性ID即可获取对应颜色。
内容的提问来源于stack exchange,提问作者oyeraghib
相关产品推荐
相关产品推荐

