Exercise - Extend an existing renderer
Note
.NET MAUI is the next evolution of Xamarin and what we recommend you develop mobile and desktop apps with, and you can learn more about .NET MAUI in several training modules. This Xamarin training module will not be maintained going forward.
In this exercise, you'll extend the provided label renderers to create a "shadowed label."
Open the starter solution
Open the XFDraw starter solution from the exercise1 > start folder in your cloned or downloaded copy of the exercise repo. There's also a final folder that contains a solution that you can use to check your work. Make sure you have these folders before you begin.
Note
If you are planning to run and debug your Xamarin apps on Android from Windows, it is best to clone or download the exercise content to a short folder path, such as C:\dev\, to avoid build-generated files exceeding the maximum path length.
Create a derived element
You'll create a new element in your shared code that derives from Label
. Later, when you create the renderers, you'll apply them to this element.
In the XFDraw shared project, create a new class named
ShadowedLabel
.Update the signature to derive from
Label
.
using Xamarin.Forms;
namespace XFDraw
{
public class ShadowedLabel : Label
{
}
}
Use the custom element
Open MainPage.xaml in the XFDraw shared project.
Notice the XML namespace named
local
, which is used to reach theXFDraw
namespace.Replace the existing
Label
with your newShadowedLabel
. Leave all existing properties as they are.
<ContentPage ...
xmlns:local="clr-namespace:XFDraw">
<Grid x:Name="mainLayout" Padding="10">
<local:ShadowedLabel Text="Microsoft Learn" HorizontalOptions="Center" VerticalOptions="End" />
</Grid>
</ContentPage>
Create the Android renderer
In the Android head-project, create a new class named
ShadowedLabelRenderer
that derives fromLabelRenderer
.Add a constructor that takes an Android
Context
and passes it to the base constructor. This step is required for Android renderers.Override
OnElementChanged
.The
Label
renderer creates an AndroidTextView
that's reachable from theControl
property. CallSetShadowLayer
on theTextView
. Use these parameter values:Control.SetShadowLayer(10, 5, 5, Android.Graphics.Color.DarkGray)
.Add the
ExportRenderer
assembly attribute above the namespace declaration to connect theShadowedLabelRenderer
to theShadowedLabel
element that you created earlier.
[assembly: ExportRenderer(typeof(ShadowedLabel), typeof(ShadowedLabelRenderer))]
namespace XFDraw.Droid
{
class ShadowedLabelRenderer : LabelRenderer
{
public ShadowedLabelRenderer(Context context) : base (context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
Control.SetShadowLayer(10, 5, 5, Android.Graphics.Color.DarkGray);
}
}
}
Create the iOS renderer
In the iOS head-project, create a new class named
ShadowedLabelRenderer
that derives fromLabelRenderer
.Override
OnElementChanged
.The
Label
renderer creates an iOSUILabel
that's reachable from theControl
property. TheUILabel
has aLayer
property that can be used to control the shadow properties. Set the values on theLayer
as shown in the following code block.Add the
ExportRenderer
assembly attribute above the namespace declaration to connect theShadowedLabelRenderer
to theShadowedLabel
element that you created earlier.
[assembly: ExportRenderer(typeof(ShadowedLabel), typeof(ShadowedLabelRenderer))]
namespace XFDraw.iOS
{
class ShadowedLabelRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
Control.Layer.ShadowColor = UIColor.DarkGray.CGColor;
Control.Layer.ShadowOpacity = 1.0f;
Control.Layer.ShadowRadius = 2f;
Control.Layer.ShadowOffset = new CGSize(4, 4);
Control.Layer.MasksToBounds = false;
}
}
}
Run the app. Notice the drop shadow below the label.