Reputation: 5597
I'm trying to wrap my head around styles and themes. I currently have a single theme in my app:
<style name="WhiteTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
</style>
I also have many styles for different views, like this:
<style name="BodyText" parent="TextAppearance.AppCompat.Body1">
<item name="android:textSize">14sp</item>
<item name="android:textColor">@color/default_text_color</item>
</style>
...which I use like this:
<TextView
...
android:textAppearance="@style/BodyText"/>
Now, if I were to create a new theme, say, a DarkTheme
, how would I ensure that all the TextViews referencing BodyText
as their TextAppearance would point to the new style?
Upvotes: 0
Views: 92
Reputation: 17105
Create an attr for the resource you would like to have different across themes.
<attr name="someTextColor" format="color"/>
Now in your themes, define the attrs
<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>
Now you can use them.
<style name="BodyText" parent="TextAppearance.AppCompat.Body1">
<item name="android:textSize">14sp</item>
<item name="android:textColor">?attr/someTextColor</item>
</style>
You can also get the attr from code
/**
* 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();
}
}
Or as 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();
}
}
Then
final int someTextColor = getColor(getTheme(), R.attr.someTextColor);
// or
final ColorStateList someTextColor = getColorStateList(getTheme(), R.attr.someTextColor);
Upvotes: 1
Reputation: 2962
Theme for 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>
Textviews which will use
<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"/>
Upvotes: 0