Adding an image to a button Android Studio is one of the most popular tasks when developing mobile applications. Visual interface elements make the application intuitive, and buttons with icons take up less screen space than text buttons. However, novice developers often have difficulties: the image is not displayed, the button is deformed, or the icon looks blurry on different devices.
In this article we will look at three main methods adding a picture to a button: through XML-markup, programmatically in Java/Kotlin, and with using Vector Asset for adaptive icons. You'll learn how to properly prepare an image, avoid stretching, and why it's sometimes better to use vector icons instead of raster ones. And at the end of the article you will find a comparative table of methods and answers to frequently asked questions.
1. Preparing an image for a button: requirements and formats
Before adding an image to a button, it needs to be properly prepared. Android Studio supports several image formats, but not all of them are equally effective:
- ๐ผ๏ธ PNG is the best choice for raster images due to its support for transparency (alpha-channel). Use for logos or complex icons.
- ๐ WebP - a modern format from Google that weighs 25-35% less
PNGwith the same quality. Recommended for animations and large images. - ๐บ Vector Drawable (XML) โvector icons that scale without losing quality. Ideal for standard icons (Material Design).
- โ JPEG โnot suitable for icons due to lack of transparency and compression artifacts.
Important to consider screen resolution. Android supports several categories of pixel density (density): ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi. For buttons, the version is usually sufficient. xxhdpi (size ~48ร48 px), but it is better to upload images for all categories through folders res/drawable-*dpi.
โ ๏ธ Attention: If you use a bitmap image (PNG/WebP) and do not provide versions for different resolutions, Android will automatically scale it, which can lead to blurriness on high pixel density screens (e.g. data-i="54">or Samsung Galaxy S23 Ultra or Google Pixel 7 Pro).
This is not a problem for vector icons - they adapt to any resolution. But if you need a raster image, use the tool Android Asset Studio (built into Android Studio), which automatically generates versions for everyone. dpicategories.
2. Method 1: Adding an image via XML markup
The easiest way to place an icon on a button โ use the attribute android:drawableLeft (or drawableRight, drawableTop, drawableBottom) in the markup file activity_main.xml. This method is suitable for static icons that do not change while the application is running.
Example code for a button with an icon on the left and text:
<Buttonandroid:id="@+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me"
android:drawableLeft="@drawable/ic_my_icon"
android:drawablePadding="8dp"
android:padding="12dp" />
Where:
- ๐
@drawable/ic_my_iconโ link to your image in the folderres/drawable. - ๐
drawablePaddingโ indentation between the icon and text (recommended8dpfor comfortable perception). - ๐
paddingโinternal padding of the button so that the icon does not โstickโ to the edges.
If you you need to place an icon without text, use ImageButton:
<ImageButtonandroid:id="@+id/imageButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_my_icon"
android:background="?attr/selectableItemBackgroundBorderless" />
โ ๏ธ Attention: Attributeandroid:backgroundwith value?attr/selectableItemBackgroundBorderlessadds a click effect (ripple effect) forImageButton. Without it, the button will look like a static image.
Added the image to the res/drawable folder|Checked the file name (without capital letters and spaces)|Specified the correct attribute (drawableLeft/Right/Top/Bottom)|Set padding (padding and drawablePadding)|Added an effect for ImageButton pressing -->
3. Method 2: Adding an image programmatically (Java/Kotlin)
If the button icon needs to change dynamically (for example, when clicked or after loading data), use programmatic addition through code. This method is flexible, but requires more code.
Example on Kotlin:
val myButton: Button = findViewById(R.id.myButton)myButton.setCompoundDrawablesWithIntrinsicBounds(
R.drawable.ic_my_icon, // left
0, // top
R.drawable.ic_arrow, // right
0 // bottom
)
myButton.compoundDrawablePadding = 8 // space between the icon and text
For Java the code will be similar, but with a different syntax:
Button myButton = findViewById(R.id.myButton);myButton.setCompoundDrawablesWithIntrinsicBounds(
R.drawable.ic_my_icon, // on the left
0, // top
R.drawable.ic_arrow, // right
0 // bottom
);
myButton.setCompoundDrawablePadding(8);
If you need change icon when clicked, use Selector (file in res/drawable):
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@drawable/ic_icon_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/ic_icon_normal"/>
</selector>
Then apply it to the button:
myButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.icon_selector, 0, 0, 0);
For ImageButton changing the icon is even easier:
val imageButton: ImageButton = findViewById(R.id.imageButton)
imageButton.setImageResource(R.drawable.ic_new_icon)
1. Is the resource ID specified correctly (for example, R.drawable.ic_my_iconand not R.drawable.ic_my_icon.png).
2. Does the file exist in the folder res/drawable.
3. Is the button overlapped by another element in the markup (use Android Studio Layout Inspector to check).-->
4. Method 3: Using Vector Asset for adaptive icons
Vector Drawable - these are vector icons that scale without losing quality. They are ideal for buttons, as they take up little space in APK and look clearly on any screen. Android Studio there is a built-in tool for the job. with them - Vector Asset Studio.
How to add a vector icon:
- In Android Studio open
File โ New โ Vector Asset. - Select Material Icon (for example,
ic_favorite,ic_search) or download yourSVGfile. - Customize the color, size and file name (for example,
ic_my_vector_icon.xml). - Click
Finishโthe file will appear in the folderres/drawable.
Now use the vector icon in the same way as raster:
<Buttonandroid:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Like"
android:drawableLeft="@drawable/ic_my_vector_icon"/>
Advantages of vector icons:
- โ
One file instead of several versions for different
dpi. - โ Clear display on any screens (including foldable devices type Samsung Galaxy Z Fold).
- โ
Ability to dynamically change color via
setTint():
myButton.compoundDrawables[0].setTint(ContextCompat.getColor(this, R.color.red))
โ ๏ธ Attention: Vector icons are not supported on Android versions below5.0 (API 21)For compatibility, add tobuild.gradleline:vectorDrawables.useSupportLibrary = trueand use
AppCompatButtoninstead of the standardButton.
How to convert SVG to Vector Drawable manually?
If you have SVG file, but Android Studio does not recognize it correctly:
1. Open the file in a text editor (for example, Notepad++).
2. Remove unnecessary tags (for example, , ).
3. Replace styles (for example, fill="#FF0000") with attributes (android:fillColor="#FF0000").
4. Save how .xml to a folder res/drawable.
An example of a correct Vector Drawable:
<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF0000"
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/>
</vector>
5. Comparison of methods: which method to choose?
Each of the three methods has its own pros and cons. The table below compares the key parameters:
| Parameter | XML markup | Programmatically (Kotlin/Java) | Vector Asset |
|---|---|---|---|
| Ease of implementation | โญโญโญโญโญ | โญโญโญ | โญโญโญโญ |
| Dynamic change | โ No | โ Yes | โ Yes (color, size) |
| Quality on different screens | โ ๏ธ Depends on resolutions | โ ๏ธ Depends on permissions | โ Ideal |
| APK size | ๐ Increases (several PNG) | ๐ Increases | โ Minimum |
| Support for older Android | โ Yes | โ Yes | โ ๏ธ Requires Support Library |
For most tasks, the optimal solution is a combination of Vector Asset for icons and programmatic modification if dynamics are needed. Raster images (PNG/WebP) should be used only for complex graphic elements that cannot reproduce vectorially (for example, logos with gradients).
Vector Asset is the best choice for standard icons (arrows, hearts, menu icons) For logos or photographs, use raster images with versions for different resolutions (mdpi, hdpi etc.).
6. Common mistakes and how to avoid them
Even experienced developers sometimes encounter problems when adding images to buttons. Here are the most common errors and their solutions:
- ๐ซ The icon is not displayed:
- Check the file name in
res/drawable(case matters!) - Make sure the file is not empty (open it in an editor)
- For vector icons, check that
build.gradlesupport is enabled:vectorDrawables.useSupportLibrary = true
- Check the file name in
- ๐ The icon is stretched or cropped:
- Use
android:scaleType="fitCenter"forImageButton - For raster images provide versions for all
dpi-categories - Check that the size of the button (
layout_width/layout_height) is not fixed (for example, thematch_parent)
- Use
- ๐จ Icon looks blurry:
- Replace the bitmap with vector
- Use Android Asset Studio to generate versions for different resolutions
- Check that the image is not lossily compressed (for example, not saved as JPEG)
- ๐ The icon does not change when clicked:
- Check that you are using
Selectorfor states (state_pressed) - For
ImageButtonaddandroid:background="?attr/selectableItemBackgroundBorderless" - Make sure that the code for changing the icon is executed in the main thread (
runOnUiThread)
- Check that you are using
If the problem is not solved, use the tool Layout Inspector v Android Studio (Tools โ Layout Inspector) It will show exactly how your button is displayed on the screen and help identify overlaps or incorrect indents.
7. Optimizing performance when working with images
Working incorrectly with images can slow down your experience. application, especially if you are using large raster files. Here are some tips for optimization:
- ๐ฑ Use
WebPinstead ofPNG:Format
WebPSupports transparency and lossless compression, reducing file size by 25-35%. You can convert images through Android Studio or online tools like Squoosh. - ๐๏ธ Remove unused resources:
In Android Studio there is a tool
Refactor โ Remove Unused Resourcesthat automatically finds and deletes unused images. - ๐ Cache images:
If icons are loaded from the network, use libraries like Glide or Picasso to cache and optimize display:
Glide.with(this).load("https://example.com/icon.png").into(imageButton); - ๐ Check the size
APK:Use
Analyze APKv Android Studio (Build โ Analyze APK) to see which resources are taking up the most space. These are often high-resolution images.
No optimization is required for vector icons - they take up minimal space and do not affect performance. However, if you use complex SVG with a large number of paths (path), simplify them in an editor like Inkscape or Adobe Illustrator.
FAQ: Answers to frequently asked questions
Is it possible to add animation to button icon?
Yes! To do this, use AnimatedVectorDrawable (for vector icons) or Drawable Animation (for raster icons). Example for vector animation:
- Create an animation file in
res/drawable(for example,avd_rotate.xml): - Add animation in
res/anim/rotate.xml: - Run the animation in code:
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"android:drawable="@drawable/ic_my_vector_icon">
<target android:name="rotationGroup" android:animation="@anim/rotate"/>
</animated-vector>
<objectAnimatorandroid:propertyName="rotation"
android:duration="1000"
android:valueFrom="0"
android:valueTo="360"/>
val avd = imageButton.drawable as AnimatedVectorDrawable
avd.start()
How to make a button with an icon round?
Use CardView or ShapeableImageView from the library Material Components:
<com.google.android.material.imageview.ShapeableImageViewandroid:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_my_icon"
app:shapeAppearanceOverlay="@style/RoundedCorners" />
B styles.xml add:
<style name="RoundedCorners"><item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
Why does the icon on the button look too small?
This is due to incorrect parameters viewportWidth/viewportHeight in a vector icon or insufficient raster image size. Solutions:
- For Vector Drawable: edit
android:widthandandroid:heighticons in the XML file (for example,24dp). - For raster images: provide versions for
xxhdpi(size ~48ร48 px) andxxxhdpi(~72ร72 px). - Enlarge
paddingbuttons:android:padding="16dp".
How to add a shadow to an icon on button?
Use CardView with the parameter cardElevation:
<androidx.cardview.widget.CardViewandroid:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardElevation="4dp"
app:cardCornerRadius="8dp">
<ImageButton
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_my_icon"
android:background="?attr/selectableItemBackgroundBorderless" />
</androidx.cardview.widget.CardView>
For more complex shadows, use MaterialShapeDrawable.
Is it possible to use a GIF as an icon on a button?
Technically yes, but this not recommended for several reasons:
- GIF increases in size
APKand consumes more memory. - The animation will play in a loop, which distracts the user.
- On some devices, GIF may slow down the interface.
It is better to use:
- AnimatedVectorDrawable for simple animations.
- Lottie (Airbnb library) for complex vector animations.
- WebP with animation (supports transparency and takes up less space than GIF).