Controls and layouts with rounded corners with Xamarin.Forms.Effect

It is not a rare case when a UI designer creates an app design full of elements with nicely rounded corners.

It can be implemented in two ways:

  • wrap each and every control into a container which will crop its content corners, a Frame with nonzero CornerRadius as an example;
  • create and apply a custom Xamarin.Forms.RoutingEffect allowing controls and layouts to crop their corners themselves.

This post provides a full implementation of the second option.

Let’s start by defining what we’d like to achieve. Here is a schematic example of a xaml applying a rounded corners effect to various layouts and controls, passing corners radius as a hardcoded number or as a resource.

Here is how it will look like on iOS and Android.

Creating an effect will require:

  1. In the shared project, declare a child of RoutingEffect, RoundCornersEffect in our case;
  2. Inside RoundCornersEffect, declare an AttachedProperty named CornerRadius;
  3. In OnCornerRadiusChanged handler, add the RoundCornersEffect to a view when the property value is more than zero and remove otherwise;
  4. In platform projects, declare a child of PlatformEffect, add an ExportEffect attribute;
  5. Override OnAttached() and OnDetached() callbacks, applying corners radius value, and OnElementPropertyChanged().

Let’s get to it!

Shared routing effect:

iOS platform effect:

Android platform effect:

GetDensity() implementation assumes Xamarin.Essentials package is referenced in the Android project. You can also implement it with Plugin.CurrentActivity package like this: CrossCurrentActivity.Current.Activity.Resources.DisplayMetrics.Density.

It came to my attention that accessing Container in OnDetached method may throw an ObjectDisposedException, which may cause the whole page UI to disappear. Hence try/catch clause in each method.

Voila!

References:

  • Xamarin documentation on Effects, especially a section explaining how to use Attached Properties to pass parameters to an effect;
  • Android documentation on ViewOutlineProvider;
  • iOS documentation on CALayer.

--

--

Anna Leushchenko πŸ‘©β€πŸ’»πŸ’™πŸ“±πŸ‡ΊπŸ‡¦

Google Developer Expert in Dart and Flutter | Author, speaker at tech events, mentor, OSS contributor | Passionate mobile apps creator