Skip to content

Instantly share code, notes, and snippets.

@r4hulp
Last active March 7, 2016 19:33
Show Gist options
  • Save r4hulp/74b97ace382757777199 to your computer and use it in GitHub Desktop.
Save r4hulp/74b97ace382757777199 to your computer and use it in GitHub Desktop.
Round ImageView extension for Xamarin Android
using Android.Content;
using Android.Content.Res;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.Util;
using Android.Views;
using Android.Widget;
namespace WrapCode.Util
{
public class CircleImageView : ImageView
{
private int borderWidth;
private int canvasSize;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
public CircleImageView(Context context)
: this(context, null)
{
}
public CircleImageView(Context context, IAttributeSet attrs)
: this(context, attrs, Resource.Attribute.circularImageViewStyle)
{
}
public CircleImageView(Context context, IAttributeSet attrs, int defStyle)
: base(context, attrs, defStyle)
{
// init paint
paint = new Paint();
paint.AntiAlias = true;
paintBorder = new Paint();
paintBorder.AntiAlias = true;
// load the styled attributes and set their properties
TypedArray attributes = context.ObtainStyledAttributes(attrs, Resource.Styleable.CircularImageView, defStyle, 0);
if (attributes.GetBoolean(Resource.Styleable.CircularImageView_border, true))
{
int defaultBorderSize = (int)(4 * context.Resources.DisplayMetrics.Density+ 0.5f);
BorderWidth = attributes.GetDimensionPixelOffset(Resource.Styleable.CircularImageView_border_width, defaultBorderSize);
BorderColor = attributes.GetColor(Resource.Styleable.CircularImageView_border_color, Color.White);
}
if (attributes.GetBoolean(Resource.Styleable.CircularImageView_shadow, false))
{
addShadow();
}
}
public void addShadow()
{
SetLayerType(LayerType.Software, paintBorder);
paintBorder.SetShadowLayer(4.0f, 0.0f, 2.0f, Color.Gray);
}
public virtual int BorderWidth
{
set
{
this.borderWidth = 5;
this.RequestLayout();
this.Invalidate();
}
}
public virtual int BorderColor
{
set
{
if (paintBorder != null)
{
paintBorder.Color = Color.Gray;
}
this.Invalidate();
}
}
protected override void OnDraw(Canvas canvas)
{
// load the bitmap
image = drawableToBitmap(Drawable);
// init shader
if (image != null)
{
canvasSize = canvas.Width;
if (canvas.Height < canvasSize)
{
canvasSize = canvas.Height;
}
BitmapShader shader = new BitmapShader(Bitmap.CreateScaledBitmap(image, canvasSize, canvasSize, false), Shader.TileMode.Clamp, Shader.TileMode.Clamp);
paint.SetShader(shader);
int circleCenter = (canvasSize - (borderWidth * 2)) / 2;
canvas.DrawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder);
canvas.DrawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint);
}
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
SetMeasuredDimension(width, height);
}
private int measureWidth(int measureSpec)
{
int result = 0;
var specMode = MeasureSpec.GetMode(measureSpec);
var specSize = MeasureSpec.GetSize(measureSpec);
if (specMode == MeasureSpecMode.Exactly)
{
// The parent has determined an exact size for the child.
result = specSize;
}
else if (specMode == MeasureSpecMode.AtMost)
{
// The child can be as large as it wants up to the specified size.
result = specSize;
}
else
{
// The parent has not imposed any constraint on the child.
result = canvasSize;
}
return result;
}
private int measureHeight(int measureSpecHeight)
{
int result = 0;
var specMode = MeasureSpec.GetMode(measureSpecHeight);
int specSize = MeasureSpec.GetSize(measureSpecHeight);
if (specMode == MeasureSpecMode.Exactly)
{
// We were told how big to be
result = specSize;
}
else if (specMode == MeasureSpecMode.AtMost)
{
// The child can be as large as it wants up to the specified size.
result = specSize;
}
else
{
// Measure the text (beware: ascent is a negative number)
result = canvasSize;
}
return (result + 2);
}
public virtual Bitmap drawableToBitmap(Drawable drawable)
{
if (drawable == null)
{
return null;
}
else if (drawable is BitmapDrawable)
{
return ((BitmapDrawable)drawable).Bitmap;
}
Bitmap bitmap = Bitmap.CreateBitmap(drawable.IntrinsicWidth, drawable.IntrinsicHeight, Bitmap.Config.Argb8888);
Canvas canvas = new Canvas(bitmap);
drawable.SetBounds(0, 0, canvas.Width, canvas.Height);
drawable.Draw(canvas);
return bitmap;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment