Android
ImageView
Circular Image
Android Development
Duplicate

How to create a circular ImageView in Android?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Circular avatar images are a common UI pattern on Android, but the best implementation depends on whether you want a quick display-only solution or a reusable component with borders and shape styling. In modern Android, the cleanest default is usually ShapeableImageView, while image-loading libraries can handle circle cropping for remote images.

Use ShapeableImageView For Modern Layouts

If your project already uses Material Components, ShapeableImageView is the easiest way to get a circular image without writing a custom view.

Add it in XML:

xml
1<com.google.android.material.imageview.ShapeableImageView
2    android:id="@+id/avatarView"
3    android:layout_width="96dp"
4    android:layout_height="96dp"
5    android:scaleType="centerCrop"
6    android:src="@drawable/profile_photo"
7    app:shapeAppearanceOverlay="@style/CircleImageShape"
8    app:strokeColor="@android:color/white"
9    app:strokeWidth="2dp" />

Then define the overlay style:

xml
1<style name="CircleImageShape">
2    <item name="cornerFamily">rounded</item>
3    <item name="cornerSize">50%</item>
4</style>

The 50% corner size is the key. It rounds the image into a circle as long as the view is square.

Load Remote Images Cleanly

If the image comes from the network, pair the view with an image-loading library. Glide is a common choice:

kotlin
1import android.os.Bundle
2import androidx.appcompat.app.AppCompatActivity
3import com.bumptech.glide.Glide
4import com.google.android.material.imageview.ShapeableImageView
5
6class ProfileActivity : AppCompatActivity() {
7    override fun onCreate(savedInstanceState: Bundle?) {
8        super.onCreate(savedInstanceState)
9        setContentView(R.layout.activity_profile)
10
11        val avatarView = findViewById<ShapeableImageView>(R.id.avatarView)
12
13        Glide.with(this)
14            .load("https://example.com/avatar.png")
15            .centerCrop()
16            .into(avatarView)
17    }
18}

Because the view itself handles the shape, the image loader does not need a special circular transform in this setup. That keeps the responsibility split cleanly:

  • Glide loads and caches the image
  • the view renders it with the correct shape

A Simpler Option With Circle Crop

If you are using a regular ImageView, Glide can crop the bitmap directly into a circle:

kotlin
1Glide.with(this)
2    .load("https://example.com/avatar.png")
3    .circleCrop()
4    .into(findViewById(R.id.avatarView))

This is useful when:

  • you do not need Material Components
  • you only care about a circular bitmap result
  • borders and advanced shape styling are not required

It is a good practical solution, especially for profile images in lists.

Why Custom Views Are Rarely Necessary Now

Older Android examples often recommend subclassing ImageView, drawing into a BitmapShader, or clipping the canvas manually. That still works, but it is usually unnecessary for modern apps.

A custom view makes sense only if you need:

  • special masking behavior
  • custom animated borders
  • unusual clipping logic

For standard circular avatars, built-in shape support or library transforms are easier to maintain and less error-prone.

Keep The View Square

A circle requires equal width and height. If the layout stretches the view into a rectangle, the result becomes an oval.

A simple square layout:

xml
1<com.google.android.material.imageview.ShapeableImageView
2    android:layout_width="72dp"
3    android:layout_height="72dp"
4    android:adjustViewBounds="false"
5    android:scaleType="centerCrop"
6    app:shapeAppearanceOverlay="@style/CircleImageShape" />

When the size is controlled by constraints or weights, double-check the measured dimensions on different screens.

XML Background Shapes Are Not Enough

A common beginner mistake is adding a circular background drawable to a normal ImageView and expecting the image itself to become circular. That only makes the background circular. The bitmap may still draw as a square on top of it.

To make the image content circular, you need either:

  • a shaped image view
  • a clipping solution
  • or an image transformation such as Glide's circleCrop

That distinction explains why some XML-only attempts appear almost correct but still show square corners.

Common Pitfalls

The most common problem is using a non-square view. Even with the right shape settings, an unequal width and height produce an oval.

Another mistake is relying only on a rounded background shape. Backgrounds do not automatically mask the image pixels inside the view.

People also forget centerCrop, which can lead to stretching or awkward letterboxing inside the circle. For avatar-style images, centerCrop is usually the right scale type.

Finally, avoid writing a custom drawing class unless you actually need it. Modern view components and image loaders already solve the basic problem well.

Summary

  • 'ShapeableImageView is the cleanest modern default for circular images on Android.'
  • Use cornerSize set to 50% and keep the view square.
  • Glide or another loader can fetch remote images while the view handles the shape.
  • 'circleCrop() is a good alternative when using a regular ImageView.'
  • A circular background alone does not make the image content circular.

Course illustration
Course illustration

All Rights Reserved.