Wednesday 13 May 2015

Layer Lists

Definition

A layer list is a drawable used to manage other drawables.
Its inflated into a LayerDrawable object in java.

Each drawable in the list is drawn in the order of the list, just like a stack of plates at the dinner table, the last drawable in the list is drawn on top.


The xml file

The list is represented by a single element with an array of elements as its children (drawables). 

Meaning each  elements  represents a drawable.

syntax:

xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:drawable="@drawable/drawable_resource"
        android:id="@id/resource_name"
        android:top="dimension"
        android:right="dimension"
        android:bottom="dimension"
        android:left="dimension" />
</layer-list>

Attributes of element:
android:drawable 
Reference to a drawable resource.

In case there is no drawable resource reference, then the drawable resource must be nested inside the elements as we are going to see in our examples

android:id

Resource ID. A unique resource ID for this drawable, by which it can be referenced from code. Retrieve and modify the drawable with View.findViewById() or Activity.findViewById().

android:top

Integer. The top offset in px/dp/dip.

android:right

Integer. The right offset in px/dp/dip.

android:bottom

Integer. The bottom offset in px/dp/dip.

android:left

Integer. The left offset in px/dp/dip.

Offset

This refers to how much space there should be between the containing view and this drawable.

To illustrate abit, incase you were viewing a stack of 2 equal-sized plates on the dinner table from the top, you'd only be able to see a single plate, the one at the top. 

Now to be able to view a plate below the top most one, you'd have to cut off some of the edge of the top one. 

The amount of diameter you remove from the top plate is equivalent to the offset and to the amount of the second plate below that you will be able to see.

Images

All drawable items are scaled to fit the size of the containing View, by default. An image may be used in the layer-list like so;

<item android:drawable="@drawable/image" />

However, this might increase the size of the View and cause some images scale as appropriate. The effect counter-acts the advantage of drawables.

To avoid scaling items in the list, use a element inside the element to specify the drawable and define the gravity to something that does not scale, such as "center". For example, the following defines an item that scales to fit its container View:

<item>
       
<bitmap android:src="@drawable/image"
          android:gravity="center" /
>
</item>

 Example

Create a new android project called LayerList and create three TextViews in the main.xml like so. We will use this example to illustrate one of the most important functions of layer-lists i.e. to create backgrounds or layered shadows.

Create 3 xml files in the drawables folder like so:
layered_no_offset.xml

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

             </shape>
       </item>
       <item>
             <shape>
                    <solid android:color="#0f0" />
             </shape>
       </item>
             <item>
             <shape>
                    <solid android:color="#00f" />
             </shape>
       </item>
</layer-list>

layered_simple_offset.xml
xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
       <item>
             <shape>
                    <solid android:color="#f00" />

             </shape>
       </item>
       <item android:top="5px" android:left="5px">
             <shape>
                    <solid android:color="#0f0" />
             </shape>
       </item>
             <item android:top="10px" android:left="10px">
             <shape>
                    <solid android:color="#00f" />
             </shape>
       </item>
</layer-list>

layered_fancy_offset.xml
xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
       <item android:bottom="10px" android:right="10px">
             <shape>
                    <solid android:color="#f00" />

             </shape>
       </item>
       <item android:top="5px" android:left="5px" android:bottom="5px" android:right="5px">
             <shape>
                    <solid android:color="#0f0" />
             </shape>
       </item>
             <item android:top="10px" android:left="10px">
             <shape>
                    <solid android:color="#00f" />
             </shape>
       </item>
</layer-list>


main.xml

xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <TextView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Layered without offset, so drawables take size of
    containing view and appear like 3 stacked plates viewed from top"
    android:layout_margin="5px"
    />
    <TextView 
    android:layout_width="fill_parent"
    android:layout_height="40px"
    android:background="@drawable/layered_no_offset"
    android:layout_margin="10px"
    />
    <TextView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Layered with left and top offsets, so drawables appear
    like 3 stacked plates and left and top edges chipped off in increasing
    amounts to the top, you can view a part of each plate from the top"
    android:layout_margin="5px"
    />
    <TextView 
    android:layout_width="fill_parent"
    android:layout_height="40px"
      android:background="@drawable/layered_simple_offset"
      android:layout_margin="10px"
    />
    <TextView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Bottom and right offsets added to some drawables, the appearance should be self-explanatory"
    android:layout_margin="5px"
    />
    <TextView 
    android:layout_width="fill_parent"
    android:layout_height="40px"
    android:background="@drawable/layered_fancy_offset"
    android:layout_margin="10px"
    />
    </LinearLayout>
</ScrollView>

We can now run our application, here is my screen shot:

Lets also check out how you'd go about using an image, for brevity, we shall use one of android's inbuilt image drawables.

Create 2 xml drawables like so

 layered_save_icon_no_offset.xml

xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
      <bitmap android:src="@android:drawable/ic_menu_save"
        android:gravity="center" />
    </item>
    <item>
      <bitmap android:src="@android:drawable/ic_menu_save"
        android:gravity="center" />
    </item>
    <item>
      <bitmap android:src="@android:drawable/ic_menu_save"
        android:gravity="center" />
    </item>
</layer-list>

 layered_save_icon_with_offset.xml
xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
      <bitmap android:src="@android:drawable/ic_menu_save"
        android:gravity="center" />
    </item>
    <item android:top="10dp" android:left="10dp">
      <bitmap android:src="@android:drawable/ic_menu_save"
        android:gravity="center" />
    </item>
    <item android:top="20dp" android:left="20dp">
      <bitmap android:src="@android:drawable/ic_menu_save"
        android:gravity="center" />
    </item>
</layer-list>

Let's go ahead and add these 2 image views in the main.xml and tell them to use our new drawables. Place them inside a horizontal linear layout.

    
    <LinearLayout   
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:weightSum="2"
     >
    <ImageView    
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:src="@drawable/layered_save_icon_no_offset"
    android:layout_weight="1"
    />
    <ImageView    
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:src="@drawable/layered_save_icon_with_offset"
    android:layout_weight="1"
    />
    </LinearLayout>

Here is my screen shot:

there you go, those are the basics of Layer lists, we shall be looking at more advanced and powerful ways of using them in later posts.

No comments:

Post a Comment