Xamarin.Forms – ListView – CustomTextCell

This project, you can find at: https://github.com/officialdoniald/Xamarin.Forms.CustomControls

We have to create some platforms specific code (custom NavigationPage Renderer), because in the base Xamarin.Forms code, we can’t find this implementation. So first step, we have to create a class in the .NET Standard/PCL project: CustomTextCell ( https://github.com/officialdoniald/Xamarin.Forms.CustomControls/blob/master/XamarinForms.CustomControls/XamarinForms.CustomControls/ListView/CustomTextCell.cs ).

using Xamarin.Forms;
namespace XamarinForms.CustomControls.ListView
{
public class CustomTextCell : TextCell
{
public static readonly BindableProperty TextFontSizeProperty =
BindableProperty.Create(“TextFontSize”, typeof(double), typeof(CustomTextCell), default(double));
public static readonly BindableProperty DetailFontSizeProperty =
BindableProperty.Create(“DetailFontSize”, typeof(double), typeof(CustomTextCell), default(double));
public static readonly BindableProperty TextFontAttributesProperty =
BindableProperty.Create(“TextFontAttributes”, typeof(Enums.FontAttributes), typeof(CustomTextCell), default(Enums.FontAttributes));
public static readonly BindableProperty TextFontFamilyProperty =
BindableProperty.Create(“TextFontFamily”, typeof(string), typeof(CustomTextCell), default(string));
public static readonly BindableProperty DetailFontAttributesProperty =
BindableProperty.Create(“DetailFontAttributes”, typeof(Enums.FontAttributes), typeof(CustomTextCell), default(Enums.FontAttributes));
public static readonly BindableProperty DetailFontFamilyProperty =
BindableProperty.Create(“DetailFontFamily”, typeof(string), typeof(CustomTextCell), default(string));
/// <summary>
/// Set the Text font size.
/// </summary>
public double TextFontSize
{
get { return (double)GetValue(TextFontSizeProperty); }
set { SetValue(TextFontSizeProperty, value); }
}
/// <summary>
/// Set the Detail font size.
/// </summary>
public double DetailFontSize
{
get { return (double)GetValue(DetailFontSizeProperty); }
set { SetValue(DetailFontSizeProperty, value); }
}
/// <summary>
/// Set the Font Attributes of the Text.
/// </summary>
public Enums.FontAttributes TextFontAttributes
{
get { return (Enums.FontAttributes)GetValue(TextFontAttributesProperty); }
set { SetValue(TextFontAttributesProperty, value); }
}
/// <summary>
/// Set the Font Family of the Text.
/// </summary>
public string TextFontFamily
{
get { return (string)GetValue(TextFontFamilyProperty); }
set { SetValue(TextFontFamilyProperty, value); }
}
/// <summary>
/// Set the Font Attributes of the Detail.
/// </summary>
public Enums.FontAttributes DetailFontAttributes
{
get { return (Enums.FontAttributes)GetValue(DetailFontAttributesProperty); }
set { SetValue(DetailFontAttributesProperty, value); }
}
/// <summary>
/// Set the Font Family of the Detail.
/// </summary>
public string DetailFontFamily
{
get { return (string)GetValue(DetailFontFamilyProperty); }
set { SetValue(DetailFontFamilyProperty, value); }
}
}
}

Enums.FontAttributes is a custtom enum class, we can create it, but we can skip it too. You can find it at: https://github.com/officialdoniald/Xamarin.Forms.CustomControls/blob/master/XamarinForms.CustomControls/XamarinForms.CustomControls/Enums/HelperEnums.cs

Now we have to implement the platform spec. code at the various platforms.

Let’s begin with the Android site ( https://github.com/officialdoniald/Xamarin.Forms.CustomControls/blob/master/XamarinForms.CustomControls/XamarinForms.CustomControls.Android/CustomRenderer/CustomTextCellRenderer.cs ):

First, we have to implement the base class’s contructor:

public CustomTextCellRenderer() : base() { }
public CustomTextCellRenderer(System.IntPtr a, Android.Runtime.JniHandleOwnership b) : base() { }

Then we have to override the GetCellCore base function:

protected override Android.Views.View GetCellCore(Cell item, Android.Views.View convertView, ViewGroup parent, Android.Content.Context context)
{
var view = (CustomTextCell)item;
if (convertView == null)
{
convertView = new BaseCellView(context, item);
}
if (convertView is BaseCellView cellView)
{
cellView.SetImageVisible(false);
cellView.MainText = view.Text;
cellView.DetailText = view.Detail;
cellView.SetMainTextColor(view.TextColor);
cellView.SetDetailTextColor(view.DetailColor);
var control = ((LinearLayout)convertView);
if (control.GetChildAt(1) is LinearLayout linearLayout)
{
var mainTextView = (TextView)linearLayout.GetChildAt(0);
var detailTextView = (TextView)linearLayout.GetChildAt(1);
mainTextView.TextSize = (float)view.TextFontSize;
detailTextView.TextSize = (float)view.DetailFontSize;
var titleTypeface = Typeface.Create(view.TextFontFamily, ConvertFontAttributesToTypefaceStyle(view.TextFontAttributes));
var detailTypeface = Typeface.Create(view.DetailFontFamily, ConvertFontAttributesToTypefaceStyle(view.DetailFontAttributes));
mainTextView.Typeface = titleTypeface;
detailTextView.Typeface = detailTypeface;
}
}
return _cellCore = convertView;
}

If we implement the custom FontAttribute enum, we have to create the ConvertFontAttributesToTypefaceStyle() function:

private TypefaceStyle ConvertFontAttributesToTypefaceStyle(Enums.FontAttributes fontAttributes)
{
if (fontAttributes == Enums.FontAttributes.Bold)
{
return Android.Graphics.TypefaceStyle.Bold;
}
else if (fontAttributes == Enums.FontAttributes.BoldItalic)
{
return Android.Graphics.TypefaceStyle.BoldItalic;
}
else if (fontAttributes == Enums.FontAttributes.Italic)
{
return Android.Graphics.TypefaceStyle.Italic;
}
else return Android.Graphics.TypefaceStyle.Normal;
}

Let’s continue with the iOS site ( https://github.com/officialdoniald/Xamarin.Forms.CustomControls/blob/master/XamarinForms.CustomControls/XamarinForms.CustomControls.iOS/CustomRenderer/CustomTextCellRenderer.cs ):

The mechanism is the same, but we don’t need to implement the base class’s constructors, but we need to override the GetCell() function:

using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using XamarinForms.CustomControls.iOS.CustomRenderer;
using XamarinForms.CustomControls.ListView;
[assembly: ExportRenderer(typeof(CustomTextCell), typeof(CustomTextCellRenderer))]
namespace XamarinForms.CustomControls.iOS.CustomRenderer
{
public class CustomTextCellRenderer : TextCellRenderer
{
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var view = (CustomTextCell)item;
var cell = base.GetCell(item, reusableCell, tv);
//cell.SelectedBackgroundView = new UIView { BackgroundColor = UIColor.Red };
var TextLabel = cell.TextLabel;
var DetailTextLabel = cell.DetailTextLabel;
TextLabel.Font = UIFont.FromName(view.TextFontFamily, (int)view.TextFontSize);
DetailTextLabel.Font = UIFont.FromName(view.DetailFontFamily, (int)view.DetailFontSize);
TextLabel.AttributedText = ConvertAttributes(TextLabel.Text, view.TextFontAttributes, (int)view.TextFontSize);
DetailTextLabel.AttributedText = ConvertAttributes(DetailTextLabel.Text, view.DetailFontAttributes, (int)view.DetailFontSize);
return cell;
}
private NSMutableAttributedString ConvertAttributes(string text, Enums.FontAttributes attr, int size)
{
if (attr == Enums.FontAttributes.Bold)
{
return new NSMutableAttributedString(
str: text,
font: UIFont.BoldSystemFontOfSize(size)
);
}
else if (attr == Enums.FontAttributes.Italic)
{
return new NSMutableAttributedString(
str: text,
font: UIFont.ItalicSystemFontOfSize(size)
);
}
//else if (attr == Enums.FontAttributes.BoldItalic)
//{
// var textattr = new NSMutableAttributedString(
// str: text,
// font: UIFont.BoldSystemFontOfSize(size)
// );
// textattr.Append(new NSMutableAttributedString(
// str: text,
// font: UIFont.ItalicSystemFontOfSize(size)
// ));
// return textattr;
//}
else
{
return new NSMutableAttributedString(
str: text,
font: UIFont.SystemFontOfSize(size)
);
}
}
}
}

52 thoughts on “Xamarin.Forms – ListView – CustomTextCell”

Leave a Reply

Your email address will not be published. Required fields are marked *