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) |
); |
} |
} |
} |
} |