如何使用特定主题的特定样式?
How to use specific styles with specific themes?
我正在努力思考风格和主题。我目前在我的应用程序中只有一个主题:
<style name="WhiteTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
</style>
我也有很多不同观点的风格,像这样:
<style name="BodyText" parent="TextAppearance.AppCompat.Body1">
<item name="android:textSize">14sp</item>
<item name="android:textColor">@color/default_text_color</item>
</style>
...我这样使用:
<TextView
...
android:textAppearance="@style/BodyText"/>
现在,如果我要创建一个新主题,比如 DarkTheme
,我如何确保所有引用 BodyText
作为其 TextAppearance 的 TextView 都指向新样式?
文本视图的主题
<style name="Theme1" parent="Theme.AppCompat.Light.DarkActionBar" >
<item name="android:textColor">@color/colorAccent</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">0.7</item>
<item name="android:textAppearance">@style/MyRedTextAppearance</item>
</style>
<style name="MyRedTextAppearance" >
<item name="android:textColor">@color/colorAccent</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">0.7</item>
</style>
<style name="Theme2" parent="Theme.AppCompat.Light.Dialog" >
<item name="android:textColor">@color/colorPrimaryDark</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">0.7</item>
<item name="android:textAppearance">@style/MyBlueTextAppearance</item>
</style>
<style name="MyBlueTextAppearance" >
<item name="android:textColor">@color/colorPrimary</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">0.7</item>
</style>
将使用
的文本视图
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Theme1"
android:text="Dummy"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Dummy"
style="@style/Theme2"/>
为您希望跨主题的资源创建一个属性。
<attr name="someTextColor" format="color"/>
现在在您的主题中,定义属性
<style name="WhiteTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="someTextColor">@android:color/black</item>
</style>
<style name="DarkTheme" parent="Theme.AppCompat">
<item name="someTextColor">@android:color/white</item>
</style>
现在您可以使用它们了。
<style name="BodyText" parent="TextAppearance.AppCompat.Body1">
<item name="android:textSize">14sp</item>
<item name="android:textColor">?attr/someTextColor</item>
</style>
你也可以通过代码获取属性
/**
* Returns color for attr from the {@link Theme}
*
* @param theme {@link Theme} to get int from
* @param attr Attribute of the int
* @return dimension for attr from the {@link Theme}
*/
@ColorInt
public static int getColor(@NonNull final Theme theme, @AttrRes final int attr) {
final TypedArray array = theme.obtainStyledAttributes(new int[]{attr});
try {
return array.getColor(0, Color.TRANSPARENT);
} finally {
array.recycle();
}
}
或作为 ColorStateList
/**
* Returns {@link ColorStateList} for attr from the {@link Theme}
*
* @param theme {@link Theme} to get int from
* @param attr Attribute of the int
* @return dimension for attr from the {@link Theme}
*/
@Nullable
public static ColorStateList getColorStateList(@NonNull final Theme theme,
@AttrRes final int attr) {
final TypedArray array = theme.obtainStyledAttributes(new int[]{attr});
try {
return array.getColorStateList(0);
} finally {
array.recycle();
}
}
然后
final int someTextColor = getColor(getTheme(), R.attr.someTextColor);
// or
final ColorStateList someTextColor = getColorStateList(getTheme(), R.attr.someTextColor);
我正在努力思考风格和主题。我目前在我的应用程序中只有一个主题:
<style name="WhiteTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
</style>
我也有很多不同观点的风格,像这样:
<style name="BodyText" parent="TextAppearance.AppCompat.Body1">
<item name="android:textSize">14sp</item>
<item name="android:textColor">@color/default_text_color</item>
</style>
...我这样使用:
<TextView
...
android:textAppearance="@style/BodyText"/>
现在,如果我要创建一个新主题,比如 DarkTheme
,我如何确保所有引用 BodyText
作为其 TextAppearance 的 TextView 都指向新样式?
文本视图的主题
<style name="Theme1" parent="Theme.AppCompat.Light.DarkActionBar" >
<item name="android:textColor">@color/colorAccent</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">0.7</item>
<item name="android:textAppearance">@style/MyRedTextAppearance</item>
</style>
<style name="MyRedTextAppearance" >
<item name="android:textColor">@color/colorAccent</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">0.7</item>
</style>
<style name="Theme2" parent="Theme.AppCompat.Light.Dialog" >
<item name="android:textColor">@color/colorPrimaryDark</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">0.7</item>
<item name="android:textAppearance">@style/MyBlueTextAppearance</item>
</style>
<style name="MyBlueTextAppearance" >
<item name="android:textColor">@color/colorPrimary</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">0.7</item>
</style>
将使用
的文本视图<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Theme1"
android:text="Dummy"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Dummy"
style="@style/Theme2"/>
为您希望跨主题的资源创建一个属性。
<attr name="someTextColor" format="color"/>
现在在您的主题中,定义属性
<style name="WhiteTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="someTextColor">@android:color/black</item>
</style>
<style name="DarkTheme" parent="Theme.AppCompat">
<item name="someTextColor">@android:color/white</item>
</style>
现在您可以使用它们了。
<style name="BodyText" parent="TextAppearance.AppCompat.Body1">
<item name="android:textSize">14sp</item>
<item name="android:textColor">?attr/someTextColor</item>
</style>
你也可以通过代码获取属性
/**
* Returns color for attr from the {@link Theme}
*
* @param theme {@link Theme} to get int from
* @param attr Attribute of the int
* @return dimension for attr from the {@link Theme}
*/
@ColorInt
public static int getColor(@NonNull final Theme theme, @AttrRes final int attr) {
final TypedArray array = theme.obtainStyledAttributes(new int[]{attr});
try {
return array.getColor(0, Color.TRANSPARENT);
} finally {
array.recycle();
}
}
或作为 ColorStateList
/**
* Returns {@link ColorStateList} for attr from the {@link Theme}
*
* @param theme {@link Theme} to get int from
* @param attr Attribute of the int
* @return dimension for attr from the {@link Theme}
*/
@Nullable
public static ColorStateList getColorStateList(@NonNull final Theme theme,
@AttrRes final int attr) {
final TypedArray array = theme.obtainStyledAttributes(new int[]{attr});
try {
return array.getColorStateList(0);
} finally {
array.recycle();
}
}
然后
final int someTextColor = getColor(getTheme(), R.attr.someTextColor);
// or
final ColorStateList someTextColor = getColorStateList(getTheme(), R.attr.someTextColor);