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 PNG with 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.

๐Ÿ“Š Which image format do you most often use in Android projects?
PNG
WebP
Vector Drawable
Other

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:

<Button

android: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 folder res/drawable.
  • ๐Ÿ”„ drawablePadding โ€” indentation between the icon and text (recommended 8dp for 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:

<ImageButton

android:id="@+id/imageButton"

android:layout_width="48dp"

android:layout_height="48dp"

android:src="@drawable/ic_my_icon"

android:background="?attr/selectableItemBackgroundBorderless" />

โš ๏ธ Attention: Attribute android:background with value ?attr/selectableItemBackgroundBorderless adds a click effect (ripple effect) for ImageButton. 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:

  1. In Android Studio open File โ†’ New โ†’ Vector Asset.
  2. Select Material Icon (for example, ic_favorite, ic_search) or download your SVGfile.
  3. Customize the color, size and file name (for example, ic_my_vector_icon.xml).
  4. Click Finish โ€”the file will appear in the folder res/drawable.

Now use the vector icon in the same way as raster:

<Button

android: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 below 5.0 (API 21)For compatibility, add to build.gradle line:
vectorDrawables.useSupportLibrary = true

and use AppCompatButton instead of the standard Button.

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.gradle support is enabled: vectorDrawables.useSupportLibrary = true
  • ๐Ÿ” The icon is stretched or cropped:
    • Use android:scaleType="fitCenter" for ImageButton
    • 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, the match_parent)
  • ๐ŸŽจ 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 Selector for states (state_pressed)
    • For ImageButton add android:background="?attr/selectableItemBackgroundBorderless"
    • Make sure that the code for changing the icon is executed in the main thread (runOnUiThread)

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 WebP instead of PNG:

    Format WebP Supports 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 APK v 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:

  1. Create an animation file in res/drawable (for example, avd_rotate.xml):
  2. <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>

  3. Add animation in res/anim/rotate.xml:
  4. <objectAnimator
    

    android:propertyName="rotation"

    android:duration="1000"

    android:valueFrom="0"

    android:valueTo="360"/>

  5. Run the animation in code:
  6. 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.ShapeableImageView

android: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:width and android:height icons in the XML file (for example, 24dp).
  • For raster images: provide versions for xxhdpi (size ~48ร—48 px) and xxxhdpi (~72ร—72 px).
  • Enlarge padding buttons: android:padding="16dp".
How to add a shadow to an icon on button?

Use CardView with the parameter cardElevation:

<androidx.cardview.widget.CardView

android: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 APK and 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).