Repeating style in v19/v21
Asked Answered
S

3

15

I have this in my styles.xml:

<style name="UserTheme" parent="ThemeBase">
    <item name="android:editTextStyle">@style/EditTextTheme</item>
</style>

Why do I have to repeat the editTextStyle line in v19/styles.xml and v21/styles.xml.

v21/styles.xml:

<style name="UserTheme" parent="ThemeBase">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
    <item name="android:editTextStyle">@style/EditTextTheme</item>
</style>

Is there a way to just call it in the main styles.xml and have it apply everywhere so I don't have to write it multiple times?

Saccharin answered 22/9, 2015 at 19:50 Comment(0)
E
19

I couldn't find any recommended solution so I i digged into AppCompat source. The way they do it is like this.

In your styles.xml

    <style name="Base.V7.Theme.YourThemeName" parent="Theme.AppCompat.Light.NoActionBar">
    </style>

    <style name="Base.Theme.YourThemeName" parent="Base.V7.Theme.YourThemeName" />

    <style name="Theme.YourThemeName" parent="Base.Theme.YourThemeName" >
       <item name="colorPrimary">@color/primary</item>
       <item name="colorPrimaryDark">@color/primary_dark</item>
       <item name="colorAccent">@color/accent</item>
    </style>

In your styles-v21.xml

    <style name="Base.V21.Theme.YourThemeName" parent="Base.V7.Theme.YourThemeName">
       <item name="android:navigationBarColor">@color/white</item>
       <item name="android:windowTranslucentStatus">true</item>
    </style>
    <style name="Base.Theme.YourThemeName" parent="Base.V21.Theme.YourThemeName" />

In your styles-v22.xml

    <style name="Base.V22.Theme.YourThemeName" parent="Base.V21.Theme.YourThemeName">
       <item name="android:navigationBarColor">@color/black</item>
       <item name="android:windowTranslucentStatus">false</item>
    </style>
    <style name="Base.Theme.YourThemeName" parent="Base.V22.Theme.YourThemeName" />

For every new version you extend the previous base version. If you want to override any attribute for different version just put it inside Base.VXX.Theme.YourThemeName block on your new styles-vXX.xml file.

Exhortative answered 28/11, 2016 at 10:7 Comment(0)
A
8
  1. Why do I have to repeat the editTextStyle line in v19/styles.xml and v21/styles.xml?

If you've applied some STYLE to some attribute, Android will search styles.xml file for highest api level for which file_api_level<=Android_device_api_level and searches for STYLE in it. If it finds it would apply that STYLE to view otherwise will continue searching for the STYLE in lower api level files.

e.g. - If you have four files styles.xml(default), v19/styles.xml, v21/styles.xml, v25/styles.xml and your devices is running on api level 24. Then it'll search for STYLE in v21/styles.xml first, then v19/styles.xml and finally in styles.xml(default). Only first occurrence of the STYLE will get applied. So you can't just define only extra attributes in version-specific styles.xml file.

If you don't want to repeat common attributes here is an alternate. To declare window transitions for Android 5.0 (API level 21) and higher, you need to use some new attributes. So your base theme in res/values/styles.xml could look like this:

<resources>
    <!-- base set of styles that apply to all versions -->
    <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/primaryColor</item>
        <item name="colorPrimaryDark">@color/primaryTextColor</item>
        <item name="colorAccent">@color/secondaryColor</item>
    </style>

    <!-- declare the theme name that's actually applied in the manifest file -->
    <style name="AppTheme" parent="BaseAppTheme" />
</resources>

Then add the version-specific styles in res/values-v21/styles.xml as follows:

<resources>
<!-- extend the base theme to add styles available only with API level 21+ -->
<style name="AppTheme" parent="BaseAppTheme">
    <item name="android:windowActivityTransitions">true</item>
    <item name="android:windowEnterTransition">@android:transition/slide_right</item>
    <item name="android:windowExitTransition">@android:transition/slide_left</item>
</style>

Now you can apply AppTheme in your manifest file and the system selects the styles available for each system version.

  1. Is there a way to just call it in the main styles.xml and have it apply everywhere so I don't have to write it multiple times?

Yes, there is a way in which you can maintain only one styles.xml file.

First of all, start using AppCompat themes. They provide backward compatibility and will work for older android versions as well.

Now define all of your styles in styles.xml(default) file and if your Android Studio is showing you some warning/error for some attribute which is supported in higher level apis: Warning from andorid studio

You can suppress that warning using: tools:targetApi="SupportedAndroidVersionName" enter image description here

Now Android will ignore that particular attribute if it's not supported and your whole style will work perfectly for both lower and higher api levels.

Read more about Styles and Themes here.

Hope it helps :)

Ames answered 23/11, 2018 at 11:6 Comment(0)
M
1

Newer versions of Android have additional themes available to applications, and you might want to use these while running on those platforms while still being compatible with older versions. You can accomplish this through a custom theme that uses resource selection to switch between different parent themes, based on the platform version.

Why do I have to repeat the editTextStyle line in v19/styles.xml and v21/styles.xml?

Because if your app is running on v21, v21/styles.xml will be loaded and if running on v19, v19/styles.xml will be loaded. In case you don't have v21/styles.xml or v19/styles.xml the app will automatically use your default values/styles.xml but you wont be able to take advantage of new features provide only for v21 or v19.

For more reference you can read Supporting Different Devices and Select a theme based on platform version.

Megrims answered 23/9, 2015 at 4:15 Comment(1)
A better question, and probably answered by this as well, (just want to confirm), does the API load styles that are defined in v19, if they aren't present in v21, when the ladder API is used? I only ask because no one likes repetition :)Hinshaw

© 2022 - 2024 — McMap. All rights reserved.