cft

Android: CircleImageView Simplified

In this article, we will talk about 3 different ways to show images in a circular shape but first let’s talk about how to pick the right 3rd party library as picking the right library to use is very important.


user

Ramiz Raja

2 years ago | 6 min read

In the past 8 years of my career, I have been part of several Android projects, from dating apps to communication and utility apps, but whatever project I joined I always found at least one library to show images in a circular shape (CircleImageView) and in some projects I also found a second library to show images with just rounded corners (not full circle).

These libraries ultimately resulted in a lot of bugs and crashes. On top of that most of these libraries were not written by well-reputed developers so no updates with bug fixes were there to update to. Replacing those in some cases cost thousands of dollars.

In this article, we will talk about 3 different ways to show images in a circular shape but first let’s talk about how to pick the right 3rd party library as picking the right library to use is very important.

Picking the Right Third-Party Library

Using a 3rd party library is not a crime and in fact, each Android project is filled with many 3rd party libraries but choosing which 3rd party library to use and which not is very important. So the following are some guidelines to help you decide which library to pick when looking for an open-source library for any platform, not just Android.

  • Pick a library that is well maintained. Go to Insights -> Contributors on GitHub and look at the contribution graph to see how often the codebase of the project is updated. For example, below is the contribution graph of our loved Retrofit Android library.

Contributions graph of the Retrofit Android library

  • Pick a library that has multiple contributors. The more the contributors the less the chances of that library getting deprecated quickly. Go to Insights -> Contributors on GitHub page of that library to find out the contributors list.
  • Pick a library that is developed and maintained by a well-reputed company like Google, Square etc.

I know not all of these checks will be checked for each library but try to check as many as you can. If you make a mistake and use a library in a large project and that library gets deprecated quickly and don’t receive any bug fixes then replacing that library may end up costing thousands of dollars (based on my experience). So please, pick the library carefully.

Now let’s come back to our main topic, the CircleImageView.

1. CircleImageView without any Library

If you look at how Android system draws views and handles view outlines then you will find out that clipping views enables you to easily change the shape of any view. Each view has a default outline that affects its shape. So a view’s shape can be easily changed by changing its outline provider to our desired shape as background and then clipping the view to that background’s outline.

First of all, let’s define a background drawable that matches the shape we desire to achieve. Oval is a good enough shape for our requirement, providing any view with a same width and height will result in a perfect circle.

<!--bg_circle.xml-->

<shape xmlns:android="http://schemas.android.com/apk/res/android"

android:shape="oval">

<solid android:color="@android:color/darker_gray"/>

</shape>

So here is how we are going to show a circular/rounded ImageView.

  1. Apply our desired shape drawable to an ImageView as background, using either android:background=”@drawable/bg_circle” in XML or using imageView.setBackgroundResource(R.drawable.bg_circle) in code.
  2. Set that ImageView’s outlineProvider to background using either android:outlineProvider="background" in XML or imageView.setOutlineProvider(ViewOutlineProvider.BACKGROUND) in code.
  3. Clip the ImageView to outline using imageView.setClipToOutline(true) (this action for some weird reason is not available in XML) so that the ImageView’s shape is same as its outline. This will result in ImageView’s shape changing to same shape as our background drawable. (Please see, only rectangle, circle, and round rectangle shapes support clipping, as determined by the Outline.canClip() method)

Because we want to reuse our CircleImageView so we will define our custom CircleImageView class and apply these attributes in that class.

class CircleImageView(

context: Context

) : AppCompatImageView(context) {

init {

//the outline (view edges) of the view should be derived from the background

outlineProvider

= ViewOutlineProvider.

BACKGROUND

//cut the view to match the view to the outline of the background

clipToOutline

= true

//use the following background to calculate the outline

setBackgroundResource(R.drawable.

bg_circle

)

//fill in the whole image view, crop if needed while keeping the center

scaleType

= ScaleType.CENTER_CROP

}

}

That’s it! Now we can use it just like any other view in our layout XML files.

<!-- Make sure width and height are same, to achieve perfect circle -->

<github.informramiz.simplecircleimageview.CircleImageView

android:layout_width="200dp"

android:layout_height="200dp"

android:src="@drawable/ironman" />

Here is how it looks!

CircleImageView

With so little code, now we have our very own CircleImageView without using any 3rd party library.

You can apply this technique to not just ImageViews but any View that supports clipping like LinearLayout, FrameLayout groups etc. In fact, by encapsulating this CircleImageView inside another similarly clipped FrameLayout you can add a circular border to this CircleImageView.

CircleImageView with Border

At the end of this article I will share the link of the GitHub repo which will contain all this code, including the code for this bordered CircleImageView.

2. CircleImageView with Material Design Components (MDC) Library

If you are already using or ready to use Material Theme as your app’s main theme then you are in luck as starting from version 1.2.0 the Material Design Components Library comes packed with a ShapeableImageView.

The shape of the ShapeableImageView can be easily controlled by updating its shapeAppearance property. You can not only make it circular but can also achieve a more fancy shape like below!

Round + Cut Corners ShapeableImageView

Here we will see a simple example of circular ShapeableImageView but in the GitHub repo you will be able to find more complex examples including the above one.

First let’s define the shape appearance in the styles.xml. You can also define shape appearance programmatically but I like to define it in XML.

<style name="ShapeAppearance.App.CircleImageView" parent="">

<item name="cornerFamily">rounded</item>

<item name="cornerSize">50%</item>

</style>

I have defined cornderFamily to be rounded (it can be cut as well) and cornerSize as 50% to achieve the right ratio for a perfect circle. You can also use the cornerRadius attribute to specificy radius in DPs if you prefer that.

Have a look at this link to find out more about possible attributes and how the material design shape theming works.

Now let’s apply this style to our ShapeableImageView as app:shapeAppearance

<com.google.android.material.imageview.ShapeableImageView

android:layout_width="200dp"

android:layout_height="200dp"

android:scaleType="centerCrop"

app:srcCompat="@drawable/ironman"

app:shapeAppearance="@style/ShapeAppearance.App.CircleImageView"/>

With this small little code we have our CircleImageView. Here is how it looks.

CircleImageView with ShapeableImageView

3. CircleImageView with Jetpack Compose

Jetpack Compose makes writing UI a breeze, all fully in Kotlin without needing any XML touch. Using Jetpack Compose we can easily show an image in circlular shape with following lines of code.

Image

(

imageResource(R.drawable.

ironman

),

modifier = Modifier

.

height

(200.

dp

)

.

width

(200.

dp

)

.

clip

(

CircleShape

),

contentScale = ContentScale.Crop

)

It follows the same idea of clipping the Image to achieve the desired shape. Here is how this one looks

CircleImageView with Jetpack Compose

So these were some examples on how to show images in a circular shape without picking a library that will get deprecated quickly resulting in a loss for the project.

I hope after reading this article you will not only use one of the above mentioned approaches to show circular images but will also pick the right third-party library when looking for a library to use for any functionality you need.

The Complete Code

Below are links to GitHub repositories containing full codes and more examples for each approach.

  1. The code for the 1st and 2nd Approach
  2. The code for the 3rd, Jetpack Compose, approach

What’s Next?

As a Sr. Android developer I see many junior developers who are good but still have certain gaps in their skills, sometimes they know many skills but don’t know how to connect the dots especially in complex use cases.

At some point in the past, I was in this same situation (with gaps in my skills and not knowing how to connect dots) so now that my gaps are a bit filled I want to help other developers like me to fill in their gaps.

If you are one of those developers then follow me here on Medium, on GitHub, and on Twitter.

Upvote


user
Created by

Ramiz Raja


people
Post

Upvote

Downvote

Comment

Bookmark

Share


Related Articles