JMRboosties
JMRboosties

Reputation: 15740

Material design: Where to place elevation in android styles?

I want to set item elevation in some of my app's styles. Now elevation is only 21 and higher with no support library, so my natural inclination was to just create a styles-v21 xml and place it in there:

<style name="Widget.MyApp.Drawer" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="android:elevation">4dp</item>
</style>

The problem with this is any changes I make to Widget.MyApp.Drawer in the regular styles.xml file will be overwritten by this completely. What I'd want is for elevation to just be tacked on to the bottom of the list of style changes I made for the v21 version of this style listed in styles.xml.

So I took to creating base styles which the style I use in the views inherits from:

<style name="BaseListElement">
    <item name="android:background">@drawable/listitem_background</item>
    <item name="android:layout_height">@dimen/list_item_height</item>
</style>

<style name="BaseListElement.ListItem">

</style>

I leave the style blank in styles.xml, and in styles-v21, I add elevation and it works.

However this get's kind of tricky when I want to use some advanced styles:

<style name="BaseListElement">
    <item name="android:background">@drawable/listitem_background</item>
    <item name="android:layout_height">@dimen/list_item_height</item>
</style>

<style name="BaseListElement.BaseItem">
    <item name="android:padding">@dimen/list_item_padding</item>
</style>

<style name="Widget.MyApp.ListItem" parent="@style/BaseListElement.BaseItem">

</style>

<style name="BaseListElement.BaseHeader">

</style>

In this case, BaseItem is just one style that inherits from BaseListElement, styles such as BaseHeader inherit from it as well. This is getting kind of ridiculous as you can see.

Am I overthinking this? The way I see it I have 3 choices here:

1) Continue as is and feel like an idiot

2) On the BaseListElement level, create a child style with some goofy name which is the point at which I apply the elevation, which would then (hopefully) trickle down to all the children. As soon as I have a difference between v21 children of the base however, this wouldn't work.

3) Just throw android:elevation into the styles.xml file (don't use a v21 file) and place an ignore flag on the element. I only have 5.0 devices here, so I can't easily test at the moment if this will cause a crash on older versions.

Any thoughts?

Upvotes: 3

Views: 2555

Answers (1)

MrEngineer13
MrEngineer13

Reputation: 38856

To accomplish something like this you could just create a BaseListElement.BaseItem in both styles.xml and syles-v21.xml the first one without the elevation and the second one with it. Then just extend Widget.MyApp.ListItem from BaseListElement.BaseItem which should get updated in v21 to use the elevation.

styles.xml

<style name="BaseListElement.BaseItem">

</style>

<style name="Widget.MyApp.ListItem" parent="@style/BaseListElement.BaseItem">

</style>

styles-v21.xml

<style name="BaseListElement.BaseItem">
    <item name="android:padding">@dimen/list_item_padding</item>
</style>

Method 3 you can safely implement as follows:

<item name="android:elevation" tools:ignore="NewApi">4dp</item>

Upvotes: 5

Related Questions