Search code examples
androidstylesandroid-themeandroid-styles

Android - Overriding a Style per Theme


Is there a way to change a style based on what theme is is set on an activity? for example, suppose my activity has a textview with a style set to TextViewStyle

<TextView
   style="@style/TextViewStyle"        
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="Text"/>

This is my TextViewStyle

<style name="TextViewStyle" parent="android:style/Widget.TextView">
        <item name="android:textStyle">bold</item>
        <item name="android:textSize">8sp</item>
        <item name="android:textColor">@android:color/holo_blue_dark</item>
    </style>

In my Styles.xml I have two themes

 <style name="AppThemeLight" parent="android:Theme.Material.Light">

   </style>


   <style name="AppThemeDark" parent="android:Theme.Material">

   </style>

Now, when I have my theme set to Dark, I want this theme to override some values I set in my TextViewStyle. How could I do this? I tried the following, but It does not work

    <!-- Override TextViewStyle style for AppThemeLight-->
            <style name ="AppThemeLight.TextBlockStyle" parent="@style/TextBlockStyle">
                <item name="android:textColor">@color/my_purple</item>
                <item name="android:textSize">20sp</item>
            </style>
<!-- Override TextViewStyle style for AppThemeDark-->
            <style name ="AppThemeDark.TextBlockStyle" parent="@style/TextBlockStyle">
                <item name="android:textColor">@color/my_green</item>
                <item name="android:textSize">40sp</item>
            </style>

Solution

  • Ok here is how I achieved this, 1 hour after posting the question! Might be helpful for someone else!

    First in attrs.xml I defined the following :

     <attr name="textBlockStyle" format="reference"/>
    

    Then in the style.xml

    <style name="TextBlockStyle" parent="android:style/Widget.TextView">
            <item name="android:textStyle">bold</item>
            <item name="android:textSize">8sp</item>
            <item name="android:textColor">@android:color/holo_blue_dark</item>
        </style>
    
        <style name="AppThemeLight" parent="android:Theme.Material.Light">
            <item name="android:windowNoTitle">true</item>
            <item name="textBlockStyle">@style/AppThemeLightTextBlockStyle</item>
        </style>
    
    
         <style name="AppThemeDark" parent="android:Theme.Material">
             <item name="android:windowNoTitle">true</item>
            <item name="textBlockStyle">@style/AppThemeDarkTextBlockStyle</item>
        </style>
    
    
    
        <!-- Override TextBlockStyle style for AppThemeLight -->
        <style name ="AppThemeLightTextBlockStyle" parent="@style/TextBlockStyle">
            <item name="android:textColor">@color/my_purple</item>
            <item name="android:textSize">20sp</item>
        </style>
        <!-- Override MyButton style for AppThemeDark -->
        <style name ="AppThemeDarkTextBlockStyle" parent="@style/TextBlockStyle">
            <item name="android:textColor">@color/my_green</item>
            <item name="android:textSize">40sp</item>
        </style>
    

    Notice how I use the attribute I defined to reference a style

    <item name="textBlockStyle">@style/AppThemeLightTextBlockStyle</item>
    

    Finally, on my element I set the style like this "style="?textBlockStyle" :

    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            style="?textBlockStyle"
            android:text="...."
            android:gravity="center" />
    

    When I set my activity theme to Dark or Light, the correct textButtenStyle will be used