Skip to content

Instantly share code, notes, and snippets.

@stackunderflows
Created May 23, 2019 17:09
Customized Xamarin.Forms Frame that allows you to specify individual corners to round.
using Android.Content;
using Android.Graphics.Drawables;
using MyApp.Controls;
using MyApp.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CustomFrame), typeof(CustomFrameRenderer))]
namespace MyApp.Droid.Renderers
{
public class CustomFrameRenderer : FrameRenderer
{
public CustomFrameRenderer(Context context)
: base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && e.OldElement == null)
{
GradientDrawable drawable = new GradientDrawable();
var frame = e.NewElement as CustomFrame;
float[] radius = new float[8];
radius[0] = frame.RoundTopLeft ? Context.ToPixels(frame.CornerRadius) : 0; //Top Left corner
radius[1] = frame.RoundTopLeft ? Context.ToPixels(frame.CornerRadius) : 0; //Top Left corner
radius[2] = frame.RoundTopRight ? Context.ToPixels(frame.CornerRadius) : 0; //Top Right corner
radius[3] = frame.RoundTopRight ? Context.ToPixels(frame.CornerRadius) : 0; //Top Right corner
radius[4] = frame.RoundBottomRight ? Context.ToPixels(frame.CornerRadius) : 0; //Bottom Right corner
radius[5] = frame.RoundBottomRight ? Context.ToPixels(frame.CornerRadius) : 0; //Bottom Right corner
radius[6] = frame.RoundBottomLeft ? Context.ToPixels(frame.CornerRadius) : 0; //Bottom Left corner
radius[7] = frame.RoundBottomLeft ? Context.ToPixels(frame.CornerRadius) : 0; //Bottom Left corner
drawable.SetCornerRadii(radius);
drawable.SetColor(frame.BackgroundColor.ToAndroid());
this.SetBackground(drawable);
}
}
}
}
using Xamarin.Forms;
namespace MyApp.Controls
{
public class CustomFrame : Frame
{
public static readonly BindableProperty RoundTopLeftProperty = BindableProperty.Create(nameof(RoundTopLeft), typeof(bool), typeof(CustomFrame), false);
public static readonly BindableProperty RoundTopRightProperty = BindableProperty.Create(nameof(RoundTopRight), typeof(bool), typeof(CustomFrame), false);
public static readonly BindableProperty RoundBottomLeftProperty = BindableProperty.Create(nameof(RoundBottomLeft), typeof(bool), typeof(CustomFrame), false);
public static readonly BindableProperty RoundBottomRightProperty = BindableProperty.Create(nameof(RoundBottomRight), typeof(bool), typeof(CustomFrame), false);
public bool RoundTopLeft
{
get { return (bool)GetValue(RoundTopLeftProperty); }
set { SetValue(RoundTopLeftProperty, value); }
}
public bool RoundTopRight
{
get { return (bool)GetValue(RoundTopRightProperty); }
set { SetValue(RoundTopLeftProperty, value); }
}
public bool RoundBottomLeft
{
get { return (bool)GetValue(RoundBottomLeftProperty); }
set { SetValue(RoundTopLeftProperty, value); }
}
public bool RoundBottomRight
{
get { return (bool)GetValue(RoundBottomRightProperty); }
set { SetValue(RoundTopLeftProperty, value); }
}
}
}
using CoreAnimation;
using MyApp.Controls;
using MyApp.iOS.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(CustomFrame), typeof(CustomFrameRenderer))]
namespace MyApp.iOS.Renderers
{
public class CustomFrameRenderer : FrameRenderer
{
public override void LayoutSublayersOfLayer(CALayer layer)
{
base.LayoutSublayersOfLayer(layer);
var frame = Element as CustomFrame;
CACornerMask corners = new CACornerMask();
if (frame.RoundTopLeft)
corners = CACornerMask.MinXMinYCorner;
if (frame.RoundTopRight)
corners = corners | CACornerMask.MaxXMinYCorner;
if (frame.RoundBottomLeft)
corners = corners | CACornerMask.MaxXMaxYCorner;
if (frame.RoundBottomRight)
corners = corners | CACornerMask.MinXMaxYCorner;
this.ClipsToBounds = true;
this.Layer.MaskedCorners = corners;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment