I've created a custom component which extends ContentView and renderer which renders to a CardView on Android.
The problem I am facing is that the Forms content is rendered below the CardView. On KitKat this does not occur, but I think the CardView implementation is not the same as on Lollipop or newer.
Setting the background color of the CardView to transparent (0x00000000) reveals the content below the CardView.
The forms component:
using Xamarin.Forms;
namespace CodeFest
{
public class NativeClientProfile : ContentView
{
public NativeClientProfile()
{
var grid = new Grid
{
RowDefinitions = new RowDefinitionCollection {new RowDefinition()},
ColumnDefinitions = new ColumnDefinitionCollection {new ColumnDefinition(), new ColumnDefinition()}
};
grid.Children.Add(new Label {Text = "FSP No"}, 0, 0);
grid.Children.Add(new Label {Text = "12345", HorizontalTextAlignment = TextAlignment.Center}, 1, 0);
grid.Children.Add(new Label {Text = "Risk"}, 0, 1);
grid.Children.Add(
new Label {Text = "Low", TextColor = Color.Green, HorizontalTextAlignment = TextAlignment.Center}, 1, 1);
var item = new Label
{
Text = "Foo bar",
HorizontalTextAlignment = TextAlignment.Center,
FontSize = 30,
FontAttributes = FontAttributes.Bold
};
Content = new StackLayout
{
Children =
{
item,
new Label
{
Text = "Financial Services Provider",
HorizontalTextAlignment = TextAlignment.Center
},
grid
}
};
}
}
}
The custom renderer:
using Android.Support.V7.Widget;
using Android.Text;
using Android.Views;
using CodeFest;
using CodeFest.Droid.ComponentRenderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(NativeClientProfile), typeof(NativeClientProfileRenderer))]
namespace CodeFest.Droid.ComponentRenderers
{
class NativeClientProfileRenderer : ViewRenderer<NativeClientProfile, CardView>
{
protected override void OnElementChanged(ElementChangedEventArgs<NativeClientProfile> elementChangedEventArgs)
{
var view = new CardView(Context);
//view.SetCardBackgroundColor(0x00000000);
SetNativeControl(view);
}
}
}
I am looking for an example of how to correctly render forms components within a CardView custom renderer.
You can use a Frame
as base class instead of ContentView
. This has the advantage, that you can use the existing FrameRenderer
of Xamarin.Forms.Platform.Android.AppCompat
which is already using a CardView
. (see: FrameRenderer.cs).
FrameRenderer declaration
public class FrameRenderer : CardView, IVisualElementRenderer, AView.IOnClickListener, AView.IOnTouchListener
Renderer
class NativeClientProfileRenderer : Xamarin.Forms.Platform.Android.AppCompat.FrameRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
}
}
NativeClientProfile
public class NativeClientProfile : Frame
{
public NativeClientProfile()
{
// your stuff...
Content = new StackLayout
{
Children =
{
item,
new Label
{
Text = "Financial Services Provider",
HorizontalTextAlignment = TextAlignment.Center
},
grid
}
};
}
}
Discussion
The renderer shows you what it needs if you really want to do it manually. Using the FrameRenderer makes your code dependent on the implementation of Xamarin. If they ever change the type of view that is rendered for a Frame
it will break your App. But if you have a look at the implementation of the FrameRenderer, I'd try to avoid creating it completely from scratch (simple risk vs. effort evaluation).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With