Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shape drawable in layer-list rendered incorrectly for APIs below 23

Yesterday, I've switched to Android Studio version 2.1.3. Today, I've re-opened one of my projects and tried to add some layer-list drawables for use with an ImageView. For example this one:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:width="80px" android:height="80px"
        android:top="0px" android:left="0px" 
        android:right="0px" android:bottom="0px">
        <shape android:shape="rectangle">
            <solid android:color="@color/deep_orange"/>
        </shape>
    </item>
    <item android:width="60px" android:height="60px"
        android:top="10px" android:left="10px" 
        android:right="10px" android:bottom="10px">
        <shape android:shape="oval">
            <solid android:color="@color/light_yellow"/>
        </shape>
    </item>
</layer-list>

yellow circle above orange square

This is what I used to get before upgrading my Android Studio version, and this is what I get now in the Preview if I choose 23 as "Android version to use when rendering layouts in the IDE".

However, if I choose any version below 23, I get just the square:

orange square, no circle

Unfortunately, I also get nothing but the square when running the app on an emulator (Lollipop 22) or a device (Jellybean 18).

Just in case this is helpful:

  • compileSdkVersion 23
  • buildToolsVersion "23.0.3"
  • minSdkVersion 11
  • targetSdkVersion 23
  • nothing for buildType debug
  • dependencies: compile 'com.android.support:appcompat-v7:23.0.1'
  • the Activity extends AppCompatActivity

I think the problem is somehow related to the use of top, left, right and bottom for the upper layer. Because if I simply place a circle on top of a square, the preview as well as the "real thing" work as expected for all API levels.

EDIT I also started a brand new project with the same code/ xml and the following (automatically created) build.gradle:

  • compileSdkVersion 24
  • buildToolsVersion "24.0.2"
  • minSdkVersion 15
  • targetSdkVersion 24
  • nothing for buildType debug
  • dependencies: compile 'com.android.support:appcompat-v7:24.2.0'
  • the Activity extends AppCompatActivity

The same behaviour here: the upper layer is not rendered for API leves <= 22 if I use top, left, right and bottom with values != 0.


So my question is: how can I create shape drawables "with insets" for all API levels using Android Studio 2.1.3?

like image 287
Bö macht Blau Avatar asked Sep 09 '16 11:09

Bö macht Blau


1 Answers

First of all, I'd like to thank @pskink for helping me to analyse the problem :)

The xml in the question worked for API level 23+, because

it is possible to set width and height right within the "item" tag

like @android developer states in this SO post

It did not work for lower versions, because there one needs to set width and height attributes for a ShapeDrawable using the size tag.

I suppose Android needs the size to figure out how to scale the drawable (-> aspect ratio!) while taking into account the insets (top, left, right, bottom).

And as is sometimes the case with malformed (for a specific API level) xml, Android failed silently and simply did not draw the shape.

So the solution is:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:width="80px" android:height="80px"
        android:top="0px" android:left="0px" 
        android:right="0px" android:bottom="0px">
        <shape android:shape="rectangle">
            <solid android:color="@color/deep_orange"/>
        </shape>
    </item>
    <item android:width="60px" android:height="60px"
        android:top="10px" android:left="10px" 
        android:right="10px" android:bottom="10px">
        <shape android:shape="oval">
            <solid android:color="@color/light_yellow"/>
            <size android:height="60px" android:width="60px"/>
        </shape>
    </item>
</layer-list>
like image 66
Bö macht Blau Avatar answered Oct 19 '22 11:10

Bö macht Blau