There are many cases where it may be more appropriate to use a circular or rounded imageview. For example if you want to show the user profiles or list users in a recyclerview. In those cases a circular imageview may be more appropriate.

Thus let’s look at libraries and examples of how to render circular imageview natively in android.

(a). Use hdodenhof/CircleImageView

CircleImageView is just that, a circular ImageView for Android.

It is fast circular ImageView perfect for profile images. This is based on RoundedImageView from Vince Mi which itself is based on techniques recommended by Romain Guy.

It uses a BitmapShader and does not:

  • create a copy of the original bitmap
  • use a clipPath (which is neither hardware accelerated nor anti-aliased)
  • use setXfermode to clip the bitmap (which means drawing twice to the canvas)

As this is just a custom ImageView and not a custom Drawable or a combination of both, it can be used with all kinds of drawables, i.e. a PicassoDrawable from Picasso or other non-standard drawables (needs some testing though).

Here is a demo:

Step 2: Use it

All you need is add it to your xml layout;

<de.hdodenhof.circleimageview.CircleImageView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/profile_image"
    android:layout_width="96dp"
    android:layout_height="96dp"
    android:src="@drawable/profile"
    app:civ_border_width="2dp"
    app:civ_border_color="#FF000000"/>

Full Example

  1. Create Android Studio Project
  2. Install the library.
  3. Design Layout

We will have the following layout:

activity_main,xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:padding="@dimen/base_padding"
        android:background="@color/light">

        <de.hdodenhof.circleimageview.CircleImageView
            android:layout_width="160dp"
            android:layout_height="160dp"
            android:layout_centerInParent="true"
            android:src="@drawable/hugh"
            app:civ_border_width="2dp"
            app:civ_border_color="@color/dark" />

    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:padding="@dimen/base_padding"
        android:background="@color/dark">

        <de.hdodenhof.circleimageview.CircleImageView
            android:layout_width="160dp"
            android:layout_height="160dp"
            android:layout_centerInParent="true"
            android:src="@drawable/hugh"
            app:civ_border_width="2dp"
            app:civ_border_color="@color/light" />

    </RelativeLayout>

</LinearLayout>

MainActivity.java

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

}

Reference

Here are the reference links:

Number link
1. Download Example
2. Read more

More Examples

Let us look at more libraries and examples:

1. Avatarview Android

Supports loading profile images with fractional styles, shapes, borders, indicators, and initials for Android..

Circular ImageView Tutorial

Circular ImageView Tutorial

AvatarView supports loading profile images with fractional style, borders, indicators, and initials for Android.

Preview

Here are demo previews:

Circular ImageView Tutorial

Circular ImageView Tutorial

Circular ImageView Tutorial

Step 1: Install it

Circular ImageView Tutorial

Add the below codes to your root build.gradle file (not your module build.gradle file).

allprojects {
    repositories {
        mavenCentral()
    }
}

Next, add the below dependency to your module's build.gradle file.

dependencies {
    implementation "io.getstream:avatarview-coil:1.0.6"
}

Note: The io.getstream.avatarview-coil dependency includes Coil to load images internally. So if you're using Coil in your project, please make sure your project is using the same Coil version or exclude Coil dependencies to adapt yours.

Including the SNAPSHOT

Snapshots of the current development version of AvatarView are available, which track the latest versions.
To import snapshot versions on your project, add the code snippet below on your gradle file.

repositories {
   maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}

Next, add the below dependency to your module's build.gradle file.

dependencies {
    implementation "io.getstream:avatarview-coil:1.0.7-SNAPSHOT"
    implementation "io.getstream:avatarview-glide:1.0.7-SNAPSHOT"
}

Step 2: Usage

First, add the following XML namespace inside your XML layout file.

xmlns:app="http://schemas.android.com/apk/res-auto"

AvatarView in XML layout

You can customize AvatarView in your XML layout by setting attributes.

<io.getstream.avatarview.AvatarView
    android:layout_width="110dp"
    android:layout_height="110dp"
    app:avatarViewBorderColor="@color/yellow"
    app:avatarViewBorderWidth="3dp"
    app:avatarViewIndicatorBorderColor="@color/white"
    app:avatarViewIndicatorBorderSizeCriteria="10"
    app:avatarViewIndicatorColor="@color/md_green_100"
    app:avatarViewIndicatorEnabled="true"
    app:avatarViewIndicatorPosition="bottomRight"
    app:avatarViewIndicatorSizeCriteria="9"
    app:avatarViewInitialsTextStyle="bold"
    app:avatarViewShape="circle" />

Loading Single Image

You can load an image on your AvatarView by using the loadImage method as in the example below:

avatarView.loadImage(data)
avatarView.loadImage(
    data = data,
    placeholder = drawable,
    onStart = {
        // started requesting an image
    },
    onComplete = {
        // completed requesting an image
    }
)

Circular ImageView Tutorial

Loading Images with Fractional Style

AvatarView supports loading up to four images with the fractional style as in the example below:

avatarView.loadImage(
  data = listof(url1, url2, url3, url4)
)

avatarViewMaxSectionSize

app:avatarViewMaxSectionSize="4"

The default value is 4, and you can set the fractional formats to your taste.
Circular ImageView Tutorial

Loading Placeholder

We can set a placeholder to show a placeholder during loading an image as in the example below:

app:avatarViewPlaceholder="@drawable/stream"

Or we can set a drawable manually on the AvatarView.

avatarView.placeholder = drawable

Circular ImageView Tutorial

Error Placeholder

We can set an error placeholder to show a placeholder when the request failed as in the example below:

app:avatarViewErrorPlaceholder="@drawable/stream"

Or we can set a drawable manually on the AvatarView.

avatarView.errorPlaceholder = drawable

Custom ImageRequest

You can customize ImageRequest and provide information to load an image as in the example below:

avatarView.loadImage(
  data = data
) {
    crossfade(true)
    crossfade(300)
    transformations(CircleCropTransformation())
    lifecycle(this@MainActivity)
}

Circular ImageView Tutorial

Border

You can customize border relevant attributes as in the example below:

<io.getstream.avatarview.AvatarView
    android:layout_width="110dp"
    android:layout_height="110dp"
    app:avatarViewBorderColor="@color/white"
    app:avatarViewBorderWidth="3dp" />

Also, you can make a gradient for the border with an avatarViewIndicatorBorderColorArray attribute. First, declare an array of color in you colors.xml file as in the example below:
avatarViewIndicatorBorderColorArray

colors.xml

<array name="rainbow">
    <item>@color/red</item>
    <item>@color/orange</item>
    <item>@color/yellow</item>
    <item>@color/chartreuse</item>
    <item>@color/green</item>
</array>

Next, apply the color array with the avatarViewBorderColor</code>Array<code>attribute instread of the</code>avatarViewBorderColor as in the below example:
avatarViewBorderColorArray
avatarViewBorderColor

<io.getstream.avatarview.AvatarView
    android:layout_width="110dp"
    android:layout_height="110dp"
    app:avatarViewBorderColorArray="@color/white"
    app:avatarViewBorderWidth="3dp" />

Circular ImageView Tutorial

Shape

AvatarView supports two shapes; circle and rounded rect. You can customize the shapes as in the example below:

Circle

You can set the shape as a circle by setting the avatarViewShape attribute to circle.
avatarViewShape

<io.getstream.avatarview.AvatarView
    android:layout_width="110dp"
    android:layout_height="110dp"
    app:avatarViewShape="circle" />
Rounded Rect

You can set the shape as a rounded rect by setting the avatarViewShape attribute to rounded_rect. Also, you can customize a radius of the border with an avatarViewBorderRadius attribute.
avatarViewShape
avatarViewBorderRadius

<io.getstream.avatarview.AvatarView
    android:layout_width="110dp"
    android:layout_height="110dp"
    app:avatarViewShape="rounded_rect"
    app:avatarViewBorderRadius="21dp"
    />

Circular ImageView Tutorial

Indicator

AvatarView supports drawing an indicator, which can be used for presenting a user online status or badges. You can enable it by giving true for an avatarViewIndicatorEnabled attribute as in the example below:
avatarViewIndicatorEnabled

<io.getstream.avatarview.AvatarView
    android:layout_width="110dp"
    android:layout_height="110dp"
    app:avatarViewIndicatorEnabled="true"
    app:avatarViewIndicatorColor="@color/green"
    app:avatarViewIndicatorBorderColor="@color/white"
    app:avatarViewIndicatorSizeCriteria="9"
    app:avatarViewIndicatorBorderSizeCriteria="10"
    app:avatarViewIndicatorPosition="bottomRight" />

As you can see above, you can customize the color of the indicator and border of the indicator, size criteria, and position. Also, you can customize the whole indicator with your custom drawable resource:

<io.getstream.avatarview.AvatarView
    android:layout_width="110dp"
    android:layout_height="110dp"
    app:avatarViewIndicatorDrawable="@drawable/stream" />

Circular ImageView Tutorial

Initials

AvatarView supports drawing initials. You can draw and customize initials instead of loading an image over the AvatarView as in the example below:

<io.getstream.avatarview.AvatarView
    android:layout_width="110dp"
    android:layout_height="110dp"
    app:avatarViewInitials="AB"
    app:avatarViewInitialsBackgroundColor="@color/skyBlue"
    app:avatarViewInitialsTextColor="@color/white"
    app:avatarViewInitialsTextSize="21sp"
    app:avatarViewInitialsTextSizeRatio="0.33"
    app:avatarViewInitialsTextStyle="bold" />

AvatarCoil

The io.getstream.avatarview-coil dependency supports customizing the internal Coil that is called AvatarCoil.
AvatarCoil

Custom ImageLoader

You can load images with your custom ImageLoader to load AvatarView by setting an ImageLoaderFactory on the AvatarCoil. Then all AvatarView will be loaded by the provided ImageLoader as in example the below:
AvatarCoil

AvatarCoil.setImageLoader(
    AvatarImageLoaderFactory(context) {
        crossfade(true)
        crossfade(400)
        okHttpClient {
            OkHttpClient.Builder()
                .cache(CoilUtils.createDefaultCache(context))
                .build()
        }
    }
)

Custom AvatarBitmapFactory

Loading custom Avatar bitmaps

Avatar bitmaps are created by the internal bitmap factory called AvatarBitmapFactory. However, you can override the image loading methods and provide your own bitmap loader like the example below:
Note: The loadAvatarBitmapBlocking method takes precedence over this one if both are implemented.

AvatarCoil.setAvatarBitmapFactory(
    object : AvatarBitmapFactory(context) {
        override suspend fun loadAvatarBitmap(data: Any?): Bitmap? {
            return withContext(Dispatchers.IO) {
                val imageResult = context.imageLoader.execute(
                    ImageRequest.Builder(context)
                       .headers(AvatarCoil.imageHeadersProvider.getImageRequestHeaders().toHeaders())
                       .data(data)
                       .build()
                )
                (imageResult.drawable as? BitmapDrawable)?.bitmap
            }
        }
    }
)

If you don't use coroutines, you can override loadAvatarBitmapBlocking method instead.

AvatarCoil.setAvatarBitmapFactory(
    object : AvatarBitmapFactory(context) {
        override fun loadAvatarBitmapBlocking(): Bitmap? {
            return // return your loaded Bitmap
        }
    }
)

Loading custom Avatar placeholder bitmaps

Basically, you can draw your placeholder drawable by setting the placeholder property on the AvatarView. However, you can provide your own bitmap loader by overriding the loadAvatarPlaceholderBitmap method like the example below:
Note: The loadAvatarPlaceholderBitmap will be executed if the previous image request failed. And the loadAvatarPlaceholderBitmapBlocking method takes precedence over this one if both are implemented.

AvatarCoil.setAvatarBitmapFactory(
    object : AvatarBitmapFactory(context) {
        override fun loadAvatarPlaceholderBitmap(): Bitmap? {
            return // return your loaded placeholder Bitmap
        }
    }
)

If you don't use coroutines, you can override loadAvatarPlaceholderBitmapBlocking method instead like the example below:

AvatarCoil.setAvatarBitmapFactory(
    object : AvatarBitmapFactory(context) {
        override fun loadAvatarPlaceholderBitmapBlocking(): Bitmap? {
            return // return your loaded placeholder Bitmap
        }
    }
)

Custom ImageHeadersProvider

If you're using your own CDN, you can set the imageHeadersProvider on AvatarCoil to load image data with your own header as in the example below:
AvatarCoil

AvatarCoil.imageHeadersProvider = yourImageHeadersProvider

AvatarView with Glide

We highly recommend using AvatarView-Coil to load images if possible. However, you can also use Glide instead.
👉 Check out AvatarView-Glide.

Stream Integration

AvatarView supports integrating features with Stream Chat SDK for Android. First, You can simply integrate with Stream Chat SDK by adding the dependency below:

dependencies {
    implementation "io.getstream:avatarview-stream-integration:$avatarview_version"
}

Next, you should set the StreamAvatarBitmapFactory on the AvatarCoil as in the below:
AvatarCoil

AvatarCoil.setAvatarBitmapFactory(StreamAvatarBitmapFactory(context))

Basically, it will load the image extra data of the User. But if there's no valid image data, the initials from the name will be loaded.
Circular ImageView Tutorial

Then you can set your User model to the AvatarView as in the example below:

val currentUser = ChatClient.instance().getCurrentUser()
avatarView.setUserData(currentUser)

Also, you can set your Channel model to the AvatarView as in the example below:

avatarView.setChannel(channel)

The channel image will be loaded. But if there is no valid channel image, an image composed of members will be loaded.

Read more Read More.