Sam Afshari's Notes
  • GitHub
  • Twitter/X
  • All posts
  • Ed
  • NuGets
  • POIWorld
  • RedCorners

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>

Back to Home


© Sam Afshari 2024