Xamarin.Android Rounded Corners Masked Layout - Sat, Aug 20, 2016
If you want to create a FrameLayout
that has real rounded corners and clips its children beyond its corners, you can use the following class, which is a port of an answer on StackOverflow. You should replace Constants.PackageName
with your Android package name, e.g. com.mycompany.myapp
.
using Android.Content;
using Android.Graphics;
using Android.Runtime;
using Android.Util;
using Android.Widget;
namespace UIWidgets.Android
{
[Register(Constants.PackageName + ".UIWidgets.Android.RoundedCornerLayout")]
public class RoundedCornerLayout : FrameLayout
{
const float CornerRadius = 20.0f;
Bitmap maskBitmap;
Paint paint, maskPaint;
float cornerRadius;
public RoundedCornerLayout(Context context) : base(context)
{
Init(context);
}
public RoundedCornerLayout(Context context, IAttributeSet attrs) : base(context, attrs)
{
Init(context, attrs);
}
public RoundedCornerLayout(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
Init(context, attrs, defStyle);
}
void Init(Context context, IAttributeSet attrs = null, int defStyle = 0)
{
DisplayMetrics metrics = Context.Resources.DisplayMetrics;
cornerRadius = TypedValue.ApplyDimension(ComplexUnitType.Dip, CornerRadius, metrics);
paint = new Paint(PaintFlags.AntiAlias);
maskPaint = new Paint(PaintFlags.AntiAlias | PaintFlags.FilterBitmap);
maskPaint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.Clear));
SetWillNotDraw(false);
}
public override void Draw(Canvas canvas)
{
Bitmap offscreenBitmap = Bitmap.CreateBitmap(canvas.Width, canvas.Height, Bitmap.Config.Argb8888);
Canvas offscreenCanvas = new Canvas(offscreenBitmap);
base.Draw(offscreenCanvas);
maskBitmap = maskBitmap ?? CreateMask(canvas.Width, canvas.Height);
offscreenCanvas.DrawBitmap(maskBitmap, 0.0f, 0.0f, maskPaint);
canvas.DrawBitmap(offscreenBitmap, 0.0f, 0.0f, paint);
}
Bitmap CreateMask(int width, int height)
{
Bitmap mask = Bitmap.CreateBitmap(width, height, Bitmap.Config.Alpha8);
Canvas canvas = new Canvas(mask);
Paint paint = new Paint(PaintFlags.AntiAlias);
paint.Color = Color.White;
canvas.DrawRect(0, 0, width, height, paint);
paint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.Clear));
canvas.DrawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);
return mask;
}
}
}
And to use it in your AXML:
<UIWidgets.Android.RoundedCornerLayout
android:layout_width="150dp"
android:layout_height="150dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFDDAA"
/>
</UIWidgets.Android.RoundedCornerLayout>