WOPR
WOPR

Reputation: 319

Drawing multiple rectangles in an xml drawable

I'm trying to figure out how to create a 3x3 row of small rectangles in an android xml drawable.
This isn't really getting me close (2 small rects, but they overlap):

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:left="20dp" android:top="20dp" android:right="25dp" android:bottom="25dp" >
        <shape android:shape="rectangle">
            <stroke android:width="1px" android:color="#fff" />
            <solid android:color="#00FF0000" />
            <corners android:radius="3dp" />
        </shape>
    </item>


    <item android:left="30dp" android:top="30dp" android:right="35dp" android:bottom="25dp" >
    <shape android:shape="rectangle">
            <stroke android:width="1px" android:color="#fff" />
            <solid android:color="#00FF0000" />
            <corners android:radius="3dp" />
            <size android:width="10dp"
                  android:height="10dp"/>
        </shape>
    </item>


</layer-list>

Upvotes: 6

Views: 16620

Answers (3)

Ted Hopp
Ted Hopp

Reputation: 234857

Part of the problem is that the individual items in a layer-list are scaled to the overall size of the drawable. As described in the docs, you can get around this by wrapping the small squares in a bitmap drawable. Something like this might work. First, define the basic shape as a separate drawable:

drawable/square.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke android:width="1px" android:color="#fff" />
    <solid android:color="#00FF0000" />
    <corners android:radius="3dp" />
    <size android:width="10dp" android:height="10dp"/>
</shape>

(EDIT: It would be nice if you could do the above, but, unfortunately, as @Someone Somewhere pointed out in a comment, you can't reference shape drawables from within a <bitmap> tag. You'll have to create the square as an actual bitmap graphic for the rest of this to work.)

Then you can define a layer-list that won't scale the individual squares:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- first row -->
    <item android:left="20dp" android:top="20dp">
        <bitmap android:src="@drawable/square" android:gravity="top|left" />
    </item>
    <item android:left="35dp" android:top="20dp">
        <bitmap android:src="@drawable/square" android:gravity="top|left" />
    </item>
    <item android:left="50dp" android:top="20dp">
        <bitmap android:src="@drawable/square" android:gravity="top|left" />
    </item>

    <!-- second row -->
    <item android:left="20dp" android:top="35dp">
        <bitmap android:src="@drawable/square" android:gravity="top|left" />
    </item>
    <item android:left="35dp" android:top="35dp">
        <bitmap android:src="@drawable/square" android:gravity="top|left" />
    </item>
    <item android:left="50dp" android:top="35dp">
        <bitmap android:src="@drawable/square" android:gravity="top|left" />
    </item>

    <!-- third row -->
    <item android:left="20dp" android:top="50dp">
        <bitmap android:src="@drawable/square" android:gravity="top|left" />
    </item>
    <item android:left="35dp" android:top="50dp">
        <bitmap android:src="@drawable/square" android:gravity="top|left" />
    </item>
    <item android:left="50dp" android:top="50dp">
        <bitmap android:src="@drawable/square" android:gravity="top|left" />
    </item>
</layer-list>

I haven't tested this, so it may be a bit off, but you should be able to tweak it to get what you want. The important thing is to get rid of the scaling.

Upvotes: 7

class stacker
class stacker

Reputation: 5347

As the discussion has already revealed, using bitmap is restricted to real bitmaps; other (XML) drawables cannot be used here.

ScaleDrawables should be a suitable solution for you. They should offer the attributes you need to adjust their position within the resulting bounding box.

However, ScaleDrawables suffer from the fact that they are intended for animations. They appear to start with a level of 0, which makes them invisibly small. Also, it does not seem possible to set the level in XML.

If you can live with setting a level on your ScaleDrawables in your code, give it a try.

Also, see this question.

Upvotes: 0

rekaszeru
rekaszeru

Reputation: 19220

Please see the documentation of Layer Lists.

It will clear up, that top, left, bottom and right are attributes in dimension for the offsets of the item: how far the item itself should be placed from the border of it's parent (the layer-list).

If you know that your layer-list is say 130 dp wide and 130 dp high, and you want 3x3 rectangles there, the first's offsets should be

top: 10
left: 10
bottom: 90
right: 90

and the next's (first row, second column):

top: 10
left: 50
bottom: 90
right: 50

Upvotes: 1

Related Questions