如何从库项目中引用应用程序主题属性?
How to refer to app theme attributes from within a library project?
我正在构建一个库,希望它尽可能通用。
所以我想将 TextView
的 textColor
属性设置为正在使用我的库的应用指定为它的 primaryColor
。
使用 android:textColor="?colorPrimary"
似乎给我一种随机颜色,而不是我的测试应用程序中指定的颜色。这可能是因为它试图在库的 R.java
文件中查找该资源 ID,而不是询问应用程序?
那么是否可以引用库范围之外的颜色?我知道我可以通过引入自定义属性来解决这个问题,但我想避免使用该解决方案,因为它需要库的用户更新他们的应用程序主题并且它不会开箱即用。
供将来参考:
我找不到基于 XML 的解决方案,但您可以在运行时以编程方式读出主题属性并从 Java 应用它们。
所以这就是我为 Android-MaterialPreference 库所做的,除了读取应用程序的 colorAccent
属性外,它还寻找一个可选的自定义 mp_colorAccent
属性,它可以覆盖默认值颜色。评论应该足够清楚。
package com.jenzz.materialpreference;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import static android.graphics.Color.parseColor;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
final class ThemeUtils {
// material_deep_teal_500
static final int FALLBACK_COLOR = parseColor("#009688");
private ThemeUtils() {
// no instances
}
static boolean isAtLeastL() {
return SDK_INT >= LOLLIPOP;
}
@TargetApi(LOLLIPOP)
static int resolveAccentColor(Context context) {
Theme theme = context.getTheme();
// on Lollipop, grab system colorAccent attribute
// pre-Lollipop, grab AppCompat colorAccent attribute
// finally, check for custom mp_colorAccent attribute
int attr = isAtLeastL() ? android.R.attr.colorAccent : R.attr.colorAccent;
TypedArray typedArray = theme.obtainStyledAttributes(new int[] { attr, R.attr.mp_colorAccent });
int accentColor = typedArray.getColor(0, FALLBACK_COLOR);
accentColor = typedArray.getColor(1, accentColor);
typedArray.recycle();
return accentColor;
}
}
我正在构建一个库,希望它尽可能通用。
所以我想将 TextView
的 textColor
属性设置为正在使用我的库的应用指定为它的 primaryColor
。
使用 android:textColor="?colorPrimary"
似乎给我一种随机颜色,而不是我的测试应用程序中指定的颜色。这可能是因为它试图在库的 R.java
文件中查找该资源 ID,而不是询问应用程序?
那么是否可以引用库范围之外的颜色?我知道我可以通过引入自定义属性来解决这个问题,但我想避免使用该解决方案,因为它需要库的用户更新他们的应用程序主题并且它不会开箱即用。
供将来参考:
我找不到基于 XML 的解决方案,但您可以在运行时以编程方式读出主题属性并从 Java 应用它们。
所以这就是我为 Android-MaterialPreference 库所做的,除了读取应用程序的 colorAccent
属性外,它还寻找一个可选的自定义 mp_colorAccent
属性,它可以覆盖默认值颜色。评论应该足够清楚。
package com.jenzz.materialpreference;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import static android.graphics.Color.parseColor;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
final class ThemeUtils {
// material_deep_teal_500
static final int FALLBACK_COLOR = parseColor("#009688");
private ThemeUtils() {
// no instances
}
static boolean isAtLeastL() {
return SDK_INT >= LOLLIPOP;
}
@TargetApi(LOLLIPOP)
static int resolveAccentColor(Context context) {
Theme theme = context.getTheme();
// on Lollipop, grab system colorAccent attribute
// pre-Lollipop, grab AppCompat colorAccent attribute
// finally, check for custom mp_colorAccent attribute
int attr = isAtLeastL() ? android.R.attr.colorAccent : R.attr.colorAccent;
TypedArray typedArray = theme.obtainStyledAttributes(new int[] { attr, R.attr.mp_colorAccent });
int accentColor = typedArray.getColor(0, FALLBACK_COLOR);
accentColor = typedArray.getColor(1, accentColor);
typedArray.recycle();
return accentColor;
}
}