ImageView in circular through xml

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


ImageView in circular through xml



I'd Like to make any image from my ImageView to be circular with a border.


ImageView



I searched but couldn't find any useful information (anything that I tried didn't work).



How can I achieve this through xml:
Create an ImageView with certain src and make it circular with a border?


ImageView





How to change the src of ImageView in java code?
– chenzhongpu
Oct 22 '14 at 14:12





Good simple solution here stackoverflow.com/a/28096369/2162226 - all in Java, so you can apply this formatting dynamically to images at runtime
– gnB
Dec 22 '16 at 0:40




15 Answers
15



You can make a simple circle with white border and transparent content with shape.


// res/drawable/circle.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="ring"
android:thicknessRatio="1.9"
android:useLevel="false" >
<solid android:color="@android:color/transparent" />

<stroke
android:width="10dp"
android:color="@android:color/white" />
</shape>



Then make a layerlist drawable and put it as background to your imageview.


// res/drawable/img.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

<item android:drawable="@drawable/ic_launcher"/>
<item android:drawable="@drawable/circle"/>

</layer-list>



and put it as background to your imageview.


<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/img"/>



You'll have something like that.



enter image description here





And then I set that shape to the background of my imageview? I've tried that but didn't work. My image still rectangular :(
– user3050910
Feb 28 '14 at 21:18





yes, using XML, because using java code is very expensive to the mobile. With this code it only appears a circle behind my image, not the image itself being a circle. I presume is for the border, I want the image to me rounded in a circle within this one
– user3050910
Feb 28 '14 at 21:25







But still something wrong. Besides the image has the circular border in front, it's not transparent outside the circle. I mean, the circle is there, however, the image corners are visible and transcends the circle area behind it
– user3050910
Feb 28 '14 at 22:13





add another shape in to the layerlist, but this time it should be rectangle with borders, it will cover corners with white
– Orhan Obut
Feb 28 '14 at 22:47





How to change the src of ImageView in java code if I adopt this way?
– chenzhongpu
Oct 22 '14 at 14:10



This is the



simplest way


dependencies: compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:cardview-v7:23.1.1'

<android.support.v7.widget.CardView
android:layout_width="80dp"
android:layout_height="80dp"
android:elevation="12dp"
android:id="@+id/view2"
app:cardCornerRadius="40dp"
android:layout_centerHorizontal="true"
android:innerRadius="0dp"
android:shape="ring"
android:thicknessRatio="1.9">
<ImageView
android:layout_height="80dp"
android:layout_width="match_parent"
android:id="@+id/imageView1"
android:src="@drawable/YOUR_IMAGE"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
</ImageView>
</android.support.v7.widget.CardView>



If you are working on android versions above lollipop


<android.support.v7.widget.CardView
android:layout_width="80dp"
android:layout_height="80dp"
android:elevation="12dp"
android:id="@+id/view2"
app:cardCornerRadius="40dp"
android:layout_centerHorizontal="true">
<ImageView
android:layout_height="80dp"
android:layout_width="match_parent"
android:id="@+id/imageView1"
android:src="@drawable/YOUR_IMAGE">
</ImageView>
</android.support.v7.widget.CardView>





nice creativity here.
– Salman Khakwani
Apr 24 '16 at 12:54





Thanks for this. Simple, and easy on memory usage. The libraries I have tried so far all give OOMExceptions when using the Custom views in RecyclerView items.
– COBB
Jul 28 '16 at 15:28





Tried using this , looks like it does not work with Android below 5.0. Even though the image view is circular, the images are smaller with square shape, looks terrible. Any suggestion? 5.0 and above works good.
– Kaps
Oct 16 '16 at 10:56





my image doesn't fit the CardView with this method
– Hendra Anggrian
Oct 19 '16 at 15:11





This makes the cardview rounded but the image is still square beneath
– kabuto178
Oct 31 '16 at 23:14



I hope this might be help you.



enter image description here


<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/profile_image"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/your_picture"
app:civ_border_color="@color/colorAccent"
app:civ_border_width="3dp" />



Note : In your project, open your_app > Gradle Scripts > build.gradle (Module: app) and add the following implementation statement to the dependencies{}


implementation 'de.hdodenhof:circleimageview:2.2.0'



For complete description please check : The Source here.





i dont know why people hates third party
– Vikrant singh
May 28 '16 at 11:04





How to change the grey color part to white ?
– John Joe
Aug 22 '16 at 16:12





There's been an update since this was posted. border_colour and border_width have been renamed. Check the github page for more info: github.com/hdodenhof/CircleImageView
– rharvey
Sep 21 '16 at 13:27





great solution @Sanjay!!
– Rushi M Thakker
Mar 27 '17 at 3:48





It worked perfectly! Thanks.
– brunoramonalmeida
Apr 1 '17 at 19:26



The above methods don't seem to work if you're using the src attribute. What I did is to put two image views inside a frame layout one above another like this:


src


<FrameLayout android:id="@+id/frame"
android:layout_width="40dp"
android:layout_height="40dp">

<ImageView android:id="@+id/pic"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/my_picture" />

<ImageView android:id="@+id/circle_crop"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/circle_crop" />

</FrameLayout>



Simply put a circular_crop.png in your drawable folder which is in the shape of your image dimensions (a square in my case) with a white background and a transparent circle in the center. You can use this image if you have want a square imageview.



Round image



Just download the picture above.





best solution! best performance. change the bitmap is memory problem
– itzhar
Oct 29 '15 at 17:04





This only works for white backgrounds?
– Kishore
Mar 16 '16 at 13:22





This sample image is white so yeah. But you can create your own image in any color or download this image and just change its color.
– Jyotman Singh
Mar 16 '16 at 13:33





Can you please explain how do I change the color of the image to black? can it be done from inside Android Studio or do I need an external tool (one can see I am not familiar with image creation)
– Zvi
Mar 27 '16 at 6:25





No not from inside Android Studio. You'll need something like Photoshop. This photo itself was also created with photoshop
– Jyotman Singh
Mar 27 '16 at 7:35



The following is one of the simplest ways to do it, use the following code:



Dependencies


dependencies {
...
compile 'de.hdodenhof:circleimageview:2.1.0' // use this or use the latest compile version. In case u get bug.
}



XML Code


<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/profile_image"
android:layout_width="96dp" // here u can adjust the width
android:layout_height="96dp" // here u can adjust the height
android:src="@drawable/profile" // here u can change the image
app:civ_border_width="2dp" // here u can adjust the border of the circle.
app:civ_border_color="#FF000000"/> // here u can adjust the border color



Screenshot:



Screenshot



Source: Circular ImageView GitHub Repository



enter image description here





Doesn't support scale type. :(
– Khan
May 3 '17 at 14:04



With the help of glide library and RoundedBitmapDrawableFactory class it's easy to achieve. You may need to create circular placeholder image.


Glide.with(context)
.load(imgUrl)
.asBitmap()
.placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder)
.into(new BitmapImageViewTarget(imgProfilePicture) {
@Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(),
Bitmap.createScaledBitmap(resource, 50, 50, false));
drawable.setCircular(true);
imgProfilePicture.setImageDrawable(drawable);
}
});





Not sure what version of glide you are using for this example, but with v4.0.0 you can simply use their RequestOptions instead of RoundedBitmapDrawable: Glide.with(context).load(imgUrl).apply(new RequestOptions().centerCrop()) .into(imageView)
– Eugene Brusov
Sep 5 '17 at 11:21




Glide.with(context).load(imgUrl).apply(new RequestOptions().centerCrop()) .into(imageView)





Don't you mean; Glide.with(context).load(imgUrl).apply(new RequestOptions().circleCrop()) .into(imageView) ?
– Androidz
Feb 13 at 9:41







With version 4.6.1 use .apply(RequestOptions.circleCropTransform())
– Pavel
Apr 10 at 16:34


.apply(RequestOptions.circleCropTransform())



I use shape = "oval" instead of the "ring" below. It has worked for me. To keep the image within bounds, I use <padding> and set <adjustViewBounds> to true in my <ImageView>. I have tried with images of size between 50 x 50 px upto 200x200 px .


<padding>


<adjustViewBounds>


<ImageView>





Can you please show an example of how you do it?
– android developer
May 17 '15 at 8:19





You can add the following as well android:scaleType="fitCenter"
– ihayet
Jun 11 at 18:18


android:scaleType="fitCenter"



This will do the trick:



rectangle.xml


<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/transparent" />
<padding android:bottom="-14dp" android:left="-14dp" android:right="-14dp" android:top="-14dp" />

</shape>



circle.xml


<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="oval"

android:useLevel="false" >
<solid android:color="@android:color/transparent" />

<stroke
android:width="15dp"
android:color="@color/verification_contact_background" />

</shape>



profile_image.xml ( The layerlist )


<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

<item android:drawable="@drawable/rectangle" />
<item android:drawable="@drawable/circle"/>

</layer-list>



Your layout


<ImageView
android:id="@+id/profile_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/default_org"
android:src="@drawable/profile_image"/>





what is default_org ?
– John Joe
Aug 22 '16 at 15:59





this can be any placeholder image
– Nidhi
Aug 24 '16 at 4:39





in this case, the edges of an image in rectangular dimension will cross the boundaries of the circle. How can I exactly position each image, in every dimension and form, inside of the circle?
– inverted_index
Oct 29 '17 at 10:58



@Jyotman Singh, answer is very good (for solid backgrounds), so I would like to enhance it by sharing vector drawable that can be re-colored for your needs, also it is convenient since vector one-piece shape is well scalable.



This is the rectangle-circle shape (@drawable/shape_round_profile_pic):


<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="284"
android:viewportHeight="284"
android:width="284dp"
android:height="284dp">
<path
android:pathData="M0 142L0 0l142 0 142 0 0 142 0 142 -142 0 -142 0zm165 137.34231c26.06742 -4.1212 52.67405 -17.543 72.66855 -36.65787 11.82805 -11.30768 20.55487 -22.85153 27.7633 -36.72531C290.23789 158.21592 285.62874 101.14121 253.48951 58.078079 217.58149 9.9651706 154.68849 -10.125717 98.348685 8.5190299 48.695824 24.95084 12.527764 67.047123 3.437787 118.98655 1.4806194 130.16966 1.511302 152.96723 3.4990422 164.5 12.168375 214.79902 47.646316 256.70775 96 273.76783c21.72002 7.66322 44.26673 9.48476 69 5.57448z"
android:fillColor="#ffffff" /> // you can change frame color
</vector>



Usage is the same:


<FrameLayout
android:layout_width="70dp"
android:layout_height="70dp">

<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/YOUR_PICTURE" />

<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shape_round_profile_pic"/>

</FrameLayout>



This Class is Custom Circular Imageview with shadow, Stroke,saturation and using this Custom Circular ImageView you can make your image in Circular Shape with Radius. Guys for Circular Shadow ImageView No need Github this class is enough.



Adding CircularImageView to your layout


CircularImageView c=new CircularImageView(this,screen width,screen height,Bitmap myimage);
yourLayout.addView(c);**


public class CircularImageView extends android.support.v7.widget.AppCompatImageView
{
private final Context context;
private final int width, height;
private final Paint paint;
private final Paint paintBorder,imagePaint;
private final Bitmap bitmap2;
private final Paint paint3;
private Bitmap bitmap;
private BitmapShader shader;
private float radius = 4.0f;
float x = 0.0f;
float y = 8.0f;
private float stroke;
private float strokeWidth = 0.0f;
private Bitmap bitmap3;
private int corner_radius=50;


public CircularImageView(Context context, int width, int height, Bitmap bitmap) {
super(context);
this.context = context;
this.width = width;
this.height = height;

//here "bitmap" is the square shape(width* width) scaled bitmap ..

this.bitmap = bitmap;


paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);


paint3=new Paint();
paint3.setStyle(Paint.Style.STROKE);
paint3.setColor(Color.WHITE);
paint3.setAntiAlias(true);

paintBorder = new Paint();
imagePaint= new Paint();

paintBorder.setColor(Color.WHITE);
paintBorder.setAntiAlias(true);
this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);


this.bitmap2 = Bitmap.createScaledBitmap(bitmap, (bitmap.getWidth() - 40), (bitmap.getHeight() - 40), true);


imagePaint.setAntiAlias(true);




invalidate();
}

@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Shader b;
if (bitmap3 != null)
b = new BitmapShader(bitmap3, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
else
b = new BitmapShader(bitmap2, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
imagePaint.setShader(b);
canvas.drawBitmap(maskedBitmap(), 20, 20, null);
}

private Bitmap maskedBitmap()
{
Bitmap l1 = Bitmap.createBitmap(width,width, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(l1);
paintBorder.setShadowLayer(radius, x, y, Color.parseColor("#454645"));
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
final RectF rect = new RectF();
rect.set(20, 20, bitmap2.getWidth(), bitmap2.getHeight());

canvas.drawRoundRect(rect, corner_radius, corner_radius, paintBorder);

canvas.drawRoundRect(rect, corner_radius, corner_radius, imagePaint);

if (strokeWidth!=0.0f)
{
paint3.setStrokeWidth(strokeWidth);
canvas.drawRoundRect(rect, corner_radius, corner_radius, paint3);
}

paint.setXfermode(null);
return l1;
}




// use seekbar here, here you have to pass "0 -- 250" here corner radius will change

public void setCornerRadius(int corner_radius)
{
this.corner_radius = corner_radius;
invalidate();
}



-------->use seekbar here, here you have to pass "0 -- 10.0f" here shadow radius will change

public void setShadow(float radius)
{
this.radius = radius;
invalidate();
}

// use seekbar here, here you have to pass "0 -- 10.0f" here stroke size will change

public void setStroke(float stroke)
{
this.strokeWidth = stroke;
invalidate();
}

private Bitmap updateSat(Bitmap src, float settingSat)
{

int w = src.getWidth();
int h = src.getHeight();

Bitmap bitmapResult =
Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvasResult = new Canvas(bitmapResult);
Paint paint = new Paint();
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(settingSat);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
paint.setColorFilter(filter);
canvasResult.drawBitmap(src, 0, 0, paint);

return bitmapResult;
}




// use seekbar here, here you have to pass "0 -- 2.0f" here saturation will change

public void setSaturation(float sat)
{
System.out.println("qqqqqqqqqq "+sat);
bitmap3=updateSat(bitmap2, sat);

invalidate();
}


}






// Seekbar to change radius

radius_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
text_radius.setText(""+progress);
circularImageView.setCornerRadius(progress);
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {

}
});


// Seekbar to change shadow

shadow_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
float f= 4+progress/10.0f;
text_shadow.setText(""+progress);
circularImageView.setShadow(f);
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {

}
});


// Seekbar to change saturation

saturation_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
int progressSat = saturation_seekbar.getProgress();
float sat = (float) ((progressSat*4 / 100.0f)-1.0f);
circularImageView.setSaturation(sat);

text_saturation.setText(""+progressSat);
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {

}
});


// Seekbar to change stroke

stroke_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
if (progress==0)
{
float f=(progress*10.0f/100.0f);
circularImageView.setStroke(f);
}
else
{
float f=(progress*10.0f/100.0f);
circularImageView.setStroke(f);
}

text_stroke.setText(""+progress);
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {

}
});




//radius seekbar in xml file

<SeekBar
android:layout_width="match_parent"
android:layout_gravity="center"
android:progress="50"
android:max="250"
android:id="@+id/radius_seekbar"
android:layout_height="wrap_content" />





//saturation seekbar in xml file

<SeekBar
android:layout_width="match_parent"
android:layout_gravity="center"
android:progress="50"
android:max="100"
android:id="@+id/saturation_seekbar"
android:layout_height="wrap_content" />





//shadow seekbar in xml file

<SeekBar
android:layout_width="match_parent"
android:layout_gravity="center"
android:progress="0"
android:max="100"
android:id="@+id/shadow_seekbar"
android:layout_height="wrap_content" />




//stroke seekbar in xml file

<SeekBar
android:layout_width="match_parent"
android:layout_gravity="center"
android:progress="0"
android:max="100"
android:id="@+id/stroke _seekbar"
android:layout_height="wrap_content" />



Actually, you can use what Google provides via the support library, instead of using a third party library :



Gradle:


implementation 'androidx.appcompat:appcompat:1.0.0-beta01'



MainActivity.kt


class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val originalDrawable = ContextCompat.getDrawable(this, R.drawable.avatar_1)!!
val bitmap = convertDrawableToBitmap(originalDrawable)
val drawable = RoundedBitmapDrawableFactory.create(resources, bitmap)
drawable.setAntiAlias(true)
drawable.cornerRadius = Math.max(bitmap.width, bitmap.height) / 2.0f
avatarImageView.setImageDrawable(drawable)
}

companion object {
@JvmStatic
fun convertDrawableToBitmap(drawable: Drawable): Bitmap {
if (drawable is BitmapDrawable)
return drawable.bitmap
// We ask for the bounds if they have been set as they would be most
// correct, then we check we are > 0
val bounds = drawable.bounds
val width = if (!bounds.isEmpty) bounds.width() else drawable.intrinsicWidth
val height = if (!bounds.isEmpty) bounds.height() else drawable.intrinsicHeight
// Now we check we are > 0
val bitmap = Bitmap.createBitmap(if (width <= 0) 1 else width, if (height <= 0) 1 else height,
Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
return bitmap
}
}
}



res/layout/activity_main.xml


<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".MainActivity">

<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/avatarImageView" android:layout_width="100dp" android:layout_height="100dp"
android:layout_gravity="center"/>

</FrameLayout>



res/drawable/avatar_1.xml


<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="128dp" android:height="128dp"
android:viewportHeight="128.0" android:viewportWidth="128.0">
<path
android:fillColor="#FF8A80" android:pathData="M0 0h128v128h-128z"/>
<path
android:fillColor="#FFE0B2"
android:pathData="M36.3 94.8c6.4 7.3 16.2 12.1 27.3 12.4 10.7,-.3 20.3,-4.7 26.7,-11.6l.2.1c-17,-13.3,-12.9,-23.4,-8.5,-28.6 1.3,-1.2 2.8,-2.5 4.4,-3.9l13.1,-11c1.5,-1.2 2.6,-3 2.9,-5.1.6,-4.4,-2.5,-8.4,-6.9,-9.1,-1.5,-.2,-3 0,-4.3.6,-.3,-1.3,-.4,-2.7,-1.6,-3.5,-1.4,-.9,-2.8,-1.7,-4.2,-2.5,-7.1,-3.9,-14.9,-6.6,-23,-7.9,-5.4,-.9,-11,-1.2,-16.1.7,-3.3 1.2,-6.1 3.2,-8.7 5.6,-1.3 1.2,-2.5 2.4,-3.7 3.7l-1.8 1.9c-.3.3,-.5.6,-.8.8,-.1.1,-.2 0,-.4.2.1.2.1.5.1.6,-1,-.3,-2.1,-.4,-3.2,-.2,-4.4.6,-7.5 4.7,-6.9 9.1.3 2.1 1.3 3.8 2.8 5.1l11 9.3c1.8 1.5 3.3 3.8 4.6 5.7 1.5 2.3 2.8 4.9 3.5 7.6 1.7 6.8,-.8 13.4,-5.4 18.4,-.5.6,-1.1 1,-1.4 1.7,-.2.6,-.4 1.3,-.6 2,-.4 1.5,-.5 3.1,-.3 4.6.4 3.1 1.8 6.1 4.1 8.2 3.3 3 8 4 12.4 4.5 5.2.6 10.5.7 15.7.2 4.5,-.4 9.1,-1.2 13,-3.4 5.6,-3.1 9.6,-8.9 10.5,-15.2m-14.4,-49.8c.9 0 1.6.7 1.6 1.6 0 .9,-.7 1.6,-1.6 1.6,-.9 0,-1.6,-.7,-1.6,-1.6,-.1,-.9.7,-1.6 1.6,-1.6zm-25.7 0c.9 0 1.6.7 1.6 1.6 0 .9,-.7 1.6,-1.6 1.6,-.9 0,-1.6,-.7,-1.6,-1.6,-.1,-.9.7,-1.6 1.6,-1.6z"/>
<path
android:fillColor="#E0F7FA"
android:pathData="M105.3 106.1c-.9,-1.3,-1.3,-1.9,-1.3,-1.9l-.2,-.3c-.6,-.9,-1.2,-1.7,-1.9,-2.4,-3.2,-3.5,-7.3,-5.4,-11.4,-5.7 0 0 .1 0 .1.1l-.2,-.1c-6.4 6.9,-16 11.3,-26.7 11.6,-11.2,-.3,-21.1,-5.1,-27.5,-12.6,-.1.2,-.2.4,-.2.5,-3.1.9,-6 2.7,-8.4 5.4l-.2.2s-.5.6,-1.5 1.7c-.9 1.1,-2.2 2.6,-3.7 4.5,-3.1 3.9,-7.2 9.5,-11.7 16.6,-.9 1.4,-1.7 2.8,-2.6 4.3h109.6c-3.4,-7.1,-6.5,-12.8,-8.9,-16.9,-1.5,-2.2,-2.6,-3.8,-3.3,-5z"/>
<path
android:fillColor="#444" android:pathData="M76.3,47.5 m-2.0, 0 a 2.0,2.0 0 1,1 4.0,0 a2.0,2.0 0 1,1 -4.0,0"/>
<path
android:fillColor="#444" android:pathData="M50.7,47.6 m-2.0, 0 a 2.0,2.0 0 1,1 4.0,0 a2.0,2.0 0 1,1 -4.0,0"/>
<path
android:fillColor="#444"
android:pathData="M48.1 27.4c4.5 5.9 15.5 12.1 42.4 8.4,-2.2,-6.9,-6.8,-12.6,-12.6,-16.4 17.2 1.5 14.1,-9.4 14.1,-9.4,-1.4 5.5,-11.1 4.4,-11.1 4.4h-18.8c-1.7,-.1,-3.4 0,-5.2.3,-12.8 1.8,-22.6 11.1,-25.7 22.9 10.6,-1.9 15.3,-7.6 16.9,-10.2z"/>
</vector>



The result:



enter image description here



And, suppose you want to add a border on top of it, you can use this for example:



stroke_drawable.xml


<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<stroke
android:width="4dp" android:color="@android:color/black"/>
</shape>



And add android:foreground="@drawable/stroke_drawable" to the ImageView in the layout XML file, and you get this :


android:foreground="@drawable/stroke_drawable"



enter image description here



use the below code, you can modify it :


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

public class RoundedImageView extends ImageView {

public RoundedImageView(Context context) {
super(context);
}

public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
protected void onDraw(Canvas canvas) {

Drawable drawable = getDrawable();

if (drawable == null) {
return;
}

if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);

int w = getWidth();
@SuppressWarnings("unused")
int h = getHeight();

Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);

}

public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;

if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sbmp = Bitmap.createScaledBitmap(bmp,
(int) (bmp.getWidth() / factor),
(int) (bmp.getHeight() / factor), false);
} else {
sbmp = bmp;
}

Bitmap output = Bitmap.createBitmap(radius, radius, Config.ARGB_8888);
Canvas canvas = new Canvas(output);

final String color = "#BAB399";
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);

paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor(color));
canvas.drawCircle(radius / 2 + 0.7f, radius / 2 + 0.7f,
radius / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);

return output;
}

}



Try this.


public class RoundedImageView extends android.support.v7.widget.AppCompatImageView {

private int borderWidth = 4;
private int viewWidth;
private int viewHeight;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
private BitmapShader shader;

public RoundedImageView(Context context)
{
super(context);
setup();
}

public RoundedImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
setup();
}

public RoundedImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
setup();
}

private void setup()
{
paint = new Paint();
paint.setAntiAlias(true);

paintBorder = new Paint();
setBorderColor(Color.WHITE);
paintBorder.setAntiAlias(true);
this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);

paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.WHITE);
}

public void setBorderWidth(int borderWidth)
{
this.borderWidth = borderWidth;
this.invalidate();
}

public void setBorderColor(int borderColor)
{
if (paintBorder != null)
paintBorder.setColor(borderColor);

this.invalidate();
}

private void loadBitmap()
{
BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();

if (bitmapDrawable != null)
image = bitmapDrawable.getBitmap();
}

@SuppressLint("DrawAllocation")
@Override
public void onDraw(Canvas canvas)
{
loadBitmap();

if (image != null)
{
shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
int circleCenter = viewWidth / 2;
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - 4.0f, paintBorder);
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - 4.0f, paint);
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec, widthMeasureSpec);

viewWidth = width - (borderWidth * 2);
viewHeight = height - (borderWidth * 2);

setMeasuredDimension(width, height);
}

private int measureWidth(int measureSpec)
{
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);

if (specMode == MeasureSpec.EXACTLY)
{
result = specSize;
}
else
{
// Measure the text
result = viewWidth;
}

return result;
}

private int measureHeight(int measureSpecHeight, int measureSpecWidth)
{
int result = 0;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);

if (specMode == MeasureSpec.EXACTLY)
{
result = specSize;
}
else
{
result = viewHeight;
}

return (result + 2);
}
}



and use this ImageView in layout like:


<com.app.Demo.RoundedImageView
android:id="@+id/iv_profileImage"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_centerHorizontal="true"
/>



As was described in Orhan Obut's answer but with the changes:


<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:src="@drawable/img"
android:layout_weight="75" />



to avoid stretches of the image.
And img.xml:


<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/profile" />
<item android:drawable="@drawable/circle" /></layer-list>



(without changes), and circle.xml:


<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadiusRatio="2"
android:shape="ring"
android:thickness="300dp"
android:useLevel="false">
<solid android:color="@android:color/white"/>
<stroke
android:width="2dp"
android:color="@android:color/black"/>
</shape>



here the thickness of the ring gotten maximal - 1000dp
and radiusRatio is a half of image width(max ring width, yes?) - 2
and the stroke is for required border if needed.
I used square png image ( profile.png ), btw. With same width and height.
This is correct for arbitrary ImageView dimentions.
enter image description here



Just use these lines of code and you are done :


<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:clickable="true"
app:civ_border_width="3dp"
app:civ_border_color="#FFFFFFFF"
android:id="@+id/profile"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_below="@+id/header_cover_image"
android:layout_centerHorizontal="true"
android:layout_marginTop="-130dp"
android:elevation="5dp"
android:padding="20dp"
android:scaleType="centerCrop"
android:src="@drawable/profilemain" />



enter image description here



Don't forget to import :


import de.hdodenhof.circleimageview.CircleImageView;



Add this library in build.gradle :


compile 'de.hdodenhof:circleimageview:2.1.0'




Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).


Would you like to answer one of these unanswered questions instead?

Popular posts from this blog

Arduino Mega cannot recieve any sketches, stk500_recv() programmer is not responding

Visual Studio Code: How to configure includePath for better IntelliSense results

C++ virtual function: Base class function is called instead of derived