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 nonzeroCornerRadius
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:
- In the shared project, declare a child of
RoutingEffect
,RoundCornersEffect
in our case; - Inside
RoundCornersEffect,
declare anAttachedProperty
namedCornerRadius
; - In
OnCornerRadiusChanged
handler, add theRoundCornersEffect
to aview
when the property value is more than zero and remove otherwise; - In platform projects, declare a child of
PlatformEffect
, add anExportEffect
attribute; - Override
OnAttached()
andOnDetached()
callbacks, applying corners radius value, andOnElementPropertyChanged()
.
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 useAttached Properties
to pass parameters to an effect; - Android documentation on
ViewOutlineProvider
; - iOS documentation on
CALayer
.