I want to make an ImageView circular. I tried the solution given here but this solution won't work for an image which is fetched from a server. I would like a solution using XML only since I prefer not to use any other alternative.
Asked
Active
Viewed 719 times
-2
-
3use this https://github.com/Pkmmte/CircularImageView – Naveen Tamrakar Sep 17 '15 at 07:51
-
Why it will not work for the extracted image from the server? oo – user2413972 Sep 17 '15 at 07:52
-
It's a good alternative, definitely. But unfortunately I'm not allowed to use external libraries. – sri Sep 17 '15 at 07:52
-
1http://www.androidhub4you.com/2014/10/android-custom-shape-imageview-rounded.html this is coustom shaps – Sohail Zahid Sep 17 '15 at 07:53
-
@user2413972: It is so because the solution fetches an image inside the layer-list from the drawable folder. I'd be grateful if you give me a workaround for this. – sri Sep 17 '15 at 07:54
-
Why you can not manually set drawable? – user2413972 Sep 17 '15 at 07:57
-
@user2413972 I precisely tried that but couldn't get it to work. I'd request you to give me a few lines of code so that I can get the idea. I've never tried this before. – sri Sep 17 '15 at 08:01
-
Naveen Tamrakar gave you perfect solution. Use it. – user2413972 Sep 17 '15 at 08:02
-
@user2413972 His solution is absolutely great, no doubt about it, but as I said earlier, I'm not allowed to use external libraries. – sri Sep 17 '15 at 08:04
3 Answers
1
No need to use library at all. Just a custom ImageView class.
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* The Class CircularImageView.
*/
public class CircularImageView extends ImageView {
/** The canvas size. */
private float canvasSize, borderWidth;
/** The image. */
private Bitmap image;
/** The paint. */
private Paint paint;
/** The paint border. */
private Paint paintBorder;
/**
* Instantiates a new circular image view.
*
* @param context
* the context
*/
public CircularImageView(final Context context) {
this(context, null);
}
/**
* Instantiates a new circular image view.
*
* @param context
* the context
* @param attrs
* the attrs
*/
public CircularImageView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.circularImageViewStyle);
}
/**
* Instantiates a new circular image view.
*
* @param context
* the context
* @param attrs
* the attrs
* @param defStyle
* the def style
*/
public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
paintBorder.setAntiAlias(true);
TypedArray attributes = context.obtainStyledAttributes(attrs,
R.styleable.CircularImageView, defStyle, 0);
if (attributes.getBoolean(R.styleable.CircularImageView_border, true)) {
setBorderWidth(attributes.getDimensionPixelOffset(
R.styleable.CircularImageView_border_width, 0));
setBorderColor(attributes.getColor(
R.styleable.CircularImageView_border_color, Color.WHITE));
}
}
/**
* Sets the border width.
*
* @param borderWidth
* the new border width
*/
public void setBorderWidth(int borderWidth) {
this.borderWidth = borderWidth;
this.requestLayout();
this.invalidate();
}
/**
* Sets the border color.
*
* @param borderColor
* the new border color
*/
public void setBorderColor(int borderColor) {
if (paintBorder != null)
paintBorder.setColor(borderColor);
this.invalidate();
}
/**
* Adds the shadow.
*/
public void addShadow() {
setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
}
/*
* (non-Javadoc)
*
* @see android.widget.ImageView#onDraw(android.graphics.Canvas)
*/
@SuppressLint("DrawAllocation")
@Override
public void onDraw(Canvas canvas) {
image = drawableToBitmap(getDrawable());
if (image != null) {
canvasSize = canvas.getWidth();
if (canvas.getHeight() < canvasSize)
canvasSize = canvas.getHeight();
BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap(
image, (int) canvasSize, (int) canvasSize, false),
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
float circleCenter = (canvasSize - (borderWidth * 2)) / 2;
canvas.drawCircle(circleCenter + borderWidth, circleCenter
+ borderWidth, ((canvasSize - (borderWidth * 2)) / 2)
+ borderWidth - 4, paintBorder);
canvas.drawCircle(circleCenter + borderWidth, circleCenter
+ borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4,
paint);
}
}
/*
* (non-Javadoc)
*
* @see android.widget.ImageView#onMeasure(int, int)
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
setMeasuredDimension(width, height);
}
/**
* Measure width.
*
* @param measureSpec
* the measure spec
* @return the int
*/
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 if (specMode == MeasureSpec.AT_MOST) {
result = specSize;
} else {
result = (int) canvasSize;
}
return result;
}
/**
* Measure height.
*
* @param measureSpecHeight
* the measure spec height
* @return the int
*/
private int measureHeight(int measureSpecHeight) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else if (specMode == MeasureSpec.AT_MOST) {
result = specSize;
} else {
result = (int) canvasSize;
}
return result;
}
/**
* Drawable to bitmap.
*
* @param drawable
* the drawable
* @return the bitmap
*/
public Bitmap drawableToBitmap(Drawable drawable) {
if (drawable == null) {
return null;
} else if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
and in attrs.xml
<declare-styleable name="CircularImageView">
<attr name="border" format="boolean"></attr>
<attr name="border_width" format="dimension"></attr>
<attr name="border_color" format="color"></attr>
<attr name="shadow" format="boolean"></attr>
</declare-styleable>
<declare-styleable name="Theme">
<attr name="circularImageViewStyle" format="reference"></attr>
</declare-styleable>
Thatsolve :)
in xml
<package.views.CircularImageView
android:id="@+id/img_pic"
android:layout_width="wrap_content"
android:layout_height="wrap-content"
android:src="@drawable/user_profile_image" />

Shadow
- 6,864
- 6
- 44
- 93
1
I have one for you. No third party dependency needed. Change src in the ImageView as background and background as src as follows image_circle.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:width="60dp"
android:height="60dp">
<shape android:shape="rectangle">
<stroke android:width="10dp" android:color="@color/white"/>
</shape>
</item>
<item android:width="60dp"
android:height="60dp">
<shape android:shape="oval">
<stroke android:color="@color/white" android:width="10dp"/>
</shape>
</item>
</layer-list>
in your layout xml
<ImageView android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/image"
android:background="@drawable/picture"/>

ZBorkala
- 366
- 3
- 13
-2
If you only want to use XML to do it the answer is : you can't.
What you need to do is to create your image view like in the ImageView in circular through xml solution you point out and programmatically set the background of the ImageView after you retrived it from the server.
In your activity :
// Retrieve the ImageView element you added to this activity
ImageView iv = findViewById(R.id.yourImageView);
// fetch your image form the server
Drawable d = //...
// Finally set the drawable to the image view.
iv.setImageDrawable(d);
This snippet will only change the background of your image view. It won't change its shape.

Community
- 1
- 1

WannaGetHigh
- 3,826
- 4
- 23
- 31