ZOFTINO.COM android and web dev tutorials

Android Drawable Resources Tutorial

A drawable resource represents a graphic file or xml drawable file that can be drawn on screen. In Android, these files are stored in res/drawable folder. To prevent blurred images, drawable resources for different screen resolutions are provided in screen resolution specific drawable folders such as drawable-mdpi, drawable-hdpi, drawable-xhdpi and drawable-xxhdpi. Please see providing and accessing android resources for more information about alternate android resources.

Different types of drawables are bitmap, xml bitmap, nine-patch, layer list, state list, level list, transition drawable, clip drawable, scale drawable and shape drawable.

Bitmap

Bitmap files are .png, .jpg and .gif. The preferred bitmap file for android is .png. Bitmap file needs to be saved in res/drawable folder and can be accessed from xml and java code. For example if you save a bitmap file panda.png in your project, you can access from xml and java code as shown below.

 <ImageButton android:id="@+id/panda"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/panda"/> 
 ((ImageButton)findViewById(R.id.panda)).setImageResource(R.drawable.panda); 

Bitmap file can be read as Drawable object using Resources object.

 Drawable panda = getResources().getDrawable(R.drawable.panda); 

XML Bitmap

You can add properties to bitamp in xml and use it as drawable. Some properties which can be added to bitmap are dither, used when image and screen pixel don’t match, filter, used to smooth bitmap appearance when it’s stretched or shrunken, and tile mode, used to repeat the image. Below is an example xml bitmap with tileMode set to mirror.

If a bitmap is smaller than its container, you can specify the position of drawable in its container using gravity attribute. Gravity attribute values such as top, bottom, left, right and center won’t scale bitmap if it is smaller than the container view.

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/zoftino"
    android:tileMode="mirror" /> 

Used it as image view background.

 <ImageView
    android:id="@+id/img"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/xml_bitmap"/> 
android xml bitmap drawable resources example

Nine-Patch File

Similar to bitmap, you can use nine-patch files and nine-patch xml. Please see create 9-patch file to know how to convert bitmap into nine-patch image file

Layer List

You can define a list of drawables in xml and use it as drawable resource in your android app. This drawable is called layer list drawable. Layer list drawable draws drawable items in the order they are defined in the xml and each drawable item is drawn on top of previous drawable item. The last drawable item is drawn on the top.

The root element of layer list drawable xml is layer-list element, you can define layers of drawable items using item element. Below is an example of layer list drawable.

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

Layer list drawable is used as value of src attribute of ImageView.

 <ImageView
    android:id="@+id/img"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/layer_list"/>
android layer list drawable example

State List

State list drawable allows you to define list of drawables for different states of a view. When state list drawable is set to one of the drawable attributes of a view, the attribute’s value is derived from the state list drawable xml for the current state of the view. As view’s state changes, value for the attribute will change to the drawable defined in the state list drawable xml for the changed state.

Root element of state list drawable xml is selector. You define drawable item for each state using item element. View states are focused, selected, pressed, hovered, checkable, clicked, enabled and activated.

Below is an example of state list drawable xml which can be used in styles as value for button attribute for checkbox. Please see custom checkbox example for more information.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true"
        android:drawable="@drawable/checked" />
    <item android:state_focused="true"
        android:drawable="@drawable/focused" />
    <item android:state_enabled="false"
        android:drawable="@drawable/diabled" />
    <item android:drawable="@drawable/unchecked" />
</selector>

Level List

Using level list drawable, drawable attributes of a view can be set to deferent drawables at run time by calling setLevel on Drawable object and passing level value to it. The level value points to a drawable in the level list drawable.

You can define level list drawable xml with different drawable items setting max and min values for each drawable. At run time, depending on the value passed to setLevel method, a drawable from the level drawable list will be picked and displayed.

Below example defines level list xml with three dawable items with different levels and level ranges. On clicking a button, level is incremented by calling setLevel on Drawable that will make it show corresponding drawable from the level list. Every time the button is clicked, image will be changed to reflect level value.

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:drawable="@drawable/square_red"
        android:maxLevel="0" />
    <item
    android:drawable="@drawable/square_blue"
    android:maxLevel="1" />
    <item
        android:drawable="@drawable/square_green"
        android:minLevel="2"
        android:maxLevel="4"/>
</level-list>

Layout xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_margin="8dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/level_list"/>
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:text="Button"/>
</LinearLayout>

Activity

public class LevelListActivity extends AppCompatActivity {
    private int levelInt = 0;
    private ImageView img;
    private Drawable drawable;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.level_list_activity);

        drawable = getResources().getDrawable(R.drawable.level_list);
        img = findViewById(R.id.img);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(levelInt >= 4){
                    levelInt = 0;
                }else{
                    levelInt++;
                }
                drawable.setLevel(levelInt);
                img.setImageDrawable(drawable);
                img.refreshDrawableState();
            }
        });
    }
}

Transition Drawable

Transition drawable allows you to define two drawable items in xml and it transitions from first drawable to second drawable on calling startTransition method on it. You can specify transition time as an argument to startTransition method. To make it transition from second drawable item to first drawable, method reverseTransition needs to be called. In the below example, every time a button is clicked, image transition will occur.

 <?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/square_red" />
    <item android:drawable="@drawable/square_green" />
</transition> 
img = findViewById(R.id.img);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        TransitionDrawable drawable = (TransitionDrawable) img.getDrawable();
        drawable.startTransition(1000);
    }
});

Inset Drawable

You can use inset drawable when the drawable is smaller than View to make it visible.

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/orange"
    android:insetTop="20dp"
    android:insetLeft="20dp" />

Clip Drawable

Clip drawable allows you to hide a drawable and slowly make it visible. By calling setLevel on drawable object and increasing the level will reveal the image slowly as the level increases. In the below example as button is clicked, image will be slowly visible.

android clip drawable example
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/android"
    android:clipOrientation="vertical"
    android:gravity="top" />
 public class ClipDrawableActivity extends AppCompatActivity {
    private int levelInt = 0;
    private ImageView img;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.clip_drawable_activity);

        img = findViewById(R.id.img);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ClipDrawable drawable = (ClipDrawable) img.getDrawable();
                levelInt = levelInt +500;
                drawable.setLevel(levelInt);
            }
        });
    }
}

Scale Drawable

Using scale drawable, you can specify how a drawable can be scaled depending on the level by setting scale height, scale width and scale gravity. Below is an example scale drawable which is displayed in image view. On clicking a button, the drawable’s level will be increased by calling setLevel and passing level. As the level increases, the drawable that is displayed in ImageView will scale.

 <?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/zoftino"
    android:scaleGravity="center_vertical|center_horizontal"
    android:scaleHeight="60%"
    android:scaleWidth="60%" />
        img = findViewById(R.id.img);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ScaleDrawable drawable = (ScaleDrawable) img.getDrawable();
                levelInt = levelInt +800;
                drawable.setLevel(levelInt);
            }
        });

Shape Drawable

Shape drawable allows you to define different shapes in xml and the defined xml can be used as value of drawable attributes of views. You can define rectangle, square, oval and ring shapes using shape drawable. For more information on shape drawables, please see shape drawable examples.