manabreak
manabreak

Reputation: 5597

How to use specific styles with specific themes?

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

Answers (2)

Yaroslav Mytkalyk
Yaroslav Mytkalyk

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

santosh kumar
santosh kumar

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

Related Questions