13

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?

Bö macht Blau
  • 12,820
  • 5
  • 40
  • 61
  • what if you set `top` and others to: `android:top="0px"` ? – pskink Sep 09 '16 at 11:33
  • @pskink - if I do this for the upper layer, then in the preview for 23 I get a 60px diameter circle in the top left corner above an orange square (80px), for 22 I get both shapes stretched to maximum in the (rectangular) preview. On my (22) emulator, the drawable fills the ImageView (80dp x 80dp) – Bö macht Blau Sep 09 '16 at 11:37
  • just run on 6.0 emulator: ` ` and it worked fine – pskink Sep 09 '16 at 11:58
  • @pskink - yes, that's just the point: 6.0 = API level 23, so no problem. But for Lollipop or Jellybean, I get no upper layer :( – Bö macht Blau Sep 09 '16 at 12:00
  • oh, right sorry, trying 5.0 now... – pskink Sep 09 '16 at 12:01
  • works like a charm on 5.0 as well so it is not a problem of `layer-list` – pskink Sep 09 '16 at 12:09
  • @pskink - I think it's something about the "new" Android Studio installation. Maybe some libraries which don't match. After all, AS recommends sometimes using a newer library (24-something) for a compileSdk-23...project, only to state that this isn't possible right after I follow its suggestion. – Bö macht Blau Sep 09 '16 at 12:14
  • did you try my xml? – pskink Sep 09 '16 at 12:17
  • @pskink - I did now. It works, so I think the problem is not so much with layer-list but more with shape drawable inside layer-list. – Bö macht Blau Sep 09 '16 at 12:25
  • exactly! try removing `android:width` / `android:height` first – pskink Sep 09 '16 at 12:26
  • @pskink - without any width/ height: the "old" project (compileSdk=23) looks the same, the "new" project (compileSdk=24) now even does not draw the circle for API level 23 preview. "Our situation has not improved" :( – Bö macht Blau Sep 09 '16 at 12:34
  • try [this](http://pastebin.com/7t7Q2tdu) LayerDrawable then, now you will know if it has anything to do with your xml build tools – pskink Sep 09 '16 at 12:57
  • @pskink - first: thank you very much for your help, I really appreciate it :) About the last drawable: well, I get an orange square (scaleType centerCrop) I suppose that's not optimal. But I think I finally managed to solve my shape drawable problem, actually quite by accident: (cont) – Bö macht Blau Sep 09 '16 at 13:18
  • (cont) I stumbled across this: [Starting from API 23, it is possible to set width and height right within the "item" tag](http://stackoverflow.com/a/38608066/5015207), and I realized that's what I've been doing: I set height and width *to the item* but not to the shape. So I added to the shapes and everything was fine :). I think I missed it all the time because my earlier AS (1.4, which I did not dare to upgrade because last time it took me a week to get the old projects running again) would have complained (I've only used compileSdk = 22 before) but the new one didn't. – Bö macht Blau Sep 09 '16 at 13:26
  • @pskink - (cont II) So once more: thanks for your help! If you like, you can write the answer and I'll be glad to accept and upvote. – Bö macht Blau Sep 09 '16 at 13:27
  • well, what should i write in the answer as it was you who found out whats wrong, glad it works now anyway... (btw did you call `GradientDrawable#setSize(int width, int height)` to find it out?) – pskink Sep 09 '16 at 13:29

1 Answers1

16

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>
Community
  • 1
  • 1
Bö macht Blau
  • 12,820
  • 5
  • 40
  • 61