In Android development, drawables play a crucial role in defining the visual elements of an application. While Android provides a variety of built-in drawables, creating custom drawables and shapes in XML can significantly enhance the user interface by providing unique and tailored visual designs. This post delves into the techniques and approaches for creating custom drawables and shapes in XML, complete with code samples.
What are Drawables in Android?
Drawables in Android are resources that can be used to draw on the screen. They serve as a graphical representation for UI elements such as backgrounds, images, or icons. Android offers several types of drawables, including:
- Bitmap Drawables: Based on raster image files (e.g., PNG, JPEG).
- Vector Drawables: Defined using XML, scalable without loss of quality.
- Shape Drawables: Defined using XML to create geometric shapes.
- Layer List Drawables: Combine multiple drawables into a single drawable.
- State List Drawables: Change appearance based on the state of a view.
- Inset Drawables: Inset another drawable by a specified distance.
- Clip Drawables: Clip another drawable based on the current level.
- Scale Drawables: Scale another drawable based on the current level.
Custom drawables allow developers to go beyond the basic shapes and create more intricate designs using XML.
Why Create Custom Drawables and Shapes in XML?
- Performance: Vector drawables and XML-defined shapes are generally more performant than bitmap images, especially for simple shapes.
- Scalability: Vector drawables scale without loss of quality across different screen densities.
- Flexibility: Easy to modify and reuse drawables by changing XML attributes.
- Maintainability: XML definitions are easier to maintain and version control compared to binary image files.
How to Create Custom Drawables and Shapes in XML
Let’s explore the steps to create custom drawables and shapes in XML with various examples.
1. Shape Drawables
Shape drawables are XML files that define geometric shapes. They can be used for backgrounds, buttons, and other UI elements.
Step 1: Create a New XML File in the drawable
Folder
In your res/drawable
directory, create a new XML file (e.g., custom_rectangle.xml
).
Step 2: Define the Shape
Use the <shape>
element as the root element to define the shape.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF4081"/>
<corners android:radius="8dp"/>
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp"/>
<size
android:width="200dp"
android:height="50dp"/>
<stroke
android:width="2dp"
android:color="#000000"/>
</shape>
Explanation:
<shape>
: Root element, defines the shape.android:shape="rectangle"
: Specifies the shape as a rectangle. Other options includeoval
,line
, andring
.<solid>
: Sets the fill color of the shape.<corners>
: Defines the radius for rounded corners.<padding>
: Adds padding inside the shape.<size>
: Specifies the width and height of the shape.<stroke>
: Adds a border around the shape.
Step 3: Use the Shape Drawable in a View
In your layout file, reference the drawable as a background:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Custom Rectangle"
android:background="@drawable/custom_rectangle"/>
2. Gradient Drawables
Gradient drawables create color transitions and add depth to the UI.
Step 1: Create a New XML File (e.g., custom_gradient.xml
)
Add a new XML file in the drawable
folder.
Step 2: Define the Gradient
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#3F51B5"
android:endColor="#E91E63"
android:angle="45"/>
<corners android:radius="10dp"/>
</shape>
Explanation:
<gradient>
: Defines the gradient.android:startColor
: The starting color of the gradient.android:endColor
: The ending color of the gradient.android:angle
: The angle of the gradient (0 is left to right, 90 is top to bottom).
Step 3: Use the Gradient Drawable
Apply the gradient drawable to a view:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Custom Gradient"
android:background="@drawable/custom_gradient"/>
3. Layer List Drawables
Layer list drawables combine multiple drawables on top of each other.
Step 1: Create a New XML File (e.g., custom_layer_list.xml
)
Create an XML file in the drawable
folder.
Step 2: Define the Layer List
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#00BCD4"/>
</shape>
</item>
<item
android:top="10dp"
android:left="10dp"
android:right="10dp"
android:bottom="10dp">
<shape android:shape="rectangle">
<solid android:color="#FFFFFF"/>
</shape>
</item>
</layer-list>
Explanation:
<layer-list>
: Root element for the layer list.<item>
: Defines each layer.android:top
,android:left
,android:right
,android:bottom
: Specify the inset for each layer.
Step 3: Use the Layer List Drawable
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Custom Layer List"
android:background="@drawable/custom_layer_list"/>
4. State List Drawables
State list drawables change their appearance based on the state of the view (e.g., pressed, focused, enabled).
Step 1: Create a New XML File (e.g., custom_button_background.xml
)
Add an XML file in the drawable
folder.
Step 2: Define the State List
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#FF4081"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#3F51B5"/>
</shape>
</item>
</selector>
Explanation:
<selector>
: Root element for the state list.<item android:state_pressed="true">
: Defines the drawable for the pressed state.- The last
<item>
is the default state.
Step 3: Use the State List Drawable
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Custom Button"
android:background="@drawable/custom_button_background"/>
5. Vector Drawables
Vector drawables use XML to define scalable graphics.
Step 1: Create a New XML File (e.g., custom_vector_drawable.xml
)
Add a new XML file in the drawable
folder.
Step 2: Define the Vector Drawable
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,16.5v-7L15,12l-5,3.5z"/>
</vector>
Explanation:
<vector>
: Root element for vector drawables.android:width
,android:height
: Define the intrinsic size of the drawable.android:viewportWidth
,android:viewportHeight
: Define the size of the virtual canvas.<path>
: Defines the shape using path data.android:fillColor
: Sets the fill color of the path.android:pathData
: The actual path commands.
Step 3: Use the Vector Drawable
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/custom_vector_drawable"/>
Best Practices for Custom Drawables and Shapes
- Use Vector Drawables for Scalability: For simple icons and shapes, vector drawables provide excellent scalability.
- Optimize Path Data: Keep the
pathData
in vector drawables as simple as possible for better performance. - Reuse Drawables: Define drawables once and reuse them across the application to maintain consistency and reduce redundancy.
- Use State Lists for Interactive Elements: For buttons and interactive views, state list drawables provide visual feedback.
- Test Across Different Devices: Ensure drawables look correct on various screen sizes and densities.
Conclusion
Creating custom drawables and shapes in XML provides a powerful way to design tailored and optimized UI elements in Android applications. Whether it’s simple shapes, gradients, layered designs, state-based changes, or scalable vector graphics, mastering custom drawables significantly enhances the visual appeal and performance of your apps. By following the guidelines and code samples outlined in this post, developers can craft unique and efficient UI elements that align with their application’s design.