Here's what I have implemented so far for iOS:
using System;
using Xamarin.Forms;
namespace Japanese
{
public class ExtCheckedTextCell: TextCell
{
public static readonly BindableProperty IsCheckedProperty =
BindableProperty.Create(
"IsChecked", typeof(bool), typeof(ExtCheckedTextCell),
defaultValue: false);
public bool IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
}
}
and my renderer looks like this:
using System;
using System.ComponentModel;
using System.Diagnostics;
using Japanese;
using Japanese.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(ExtCheckedTextCell), typeof(ExtCheckedTextCellRenderer))]
namespace Japanese.iOS
{
public class ExtCheckedTextCellRenderer : TextCellRenderer
{
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var nativeCell = base.GetCell(item, reusableCell, tv);
if (item is ExtCheckedTextCell formsCell)
{
SetCheckmark(nativeCell, formsCell);
SetTap(nativeCell, formsCell);
}
return nativeCell;
}
protected override void HandlePropertyChanged(object sender, PropertyChangedEventArgs args)
{
base.HandlePropertyChanged(sender, args);
System.Diagnostics.Debug.WriteLine($"HandlePropertyChanged {args.PropertyName}");
var nativeCell = sender as CellTableViewCell;
if (nativeCell?.Element is ExtCheckedTextCell formsCell)
{
if (args.PropertyName == ExtCheckedTextCell.IsCheckedProperty.PropertyName)
SetCheckmark(nativeCell, formsCell);
}
}
void SetCheckmark(UITableViewCell nativeCell, ExtCheckedTextCell formsCell)
{
if (formsCell.IsChecked)
nativeCell.Accessory = UITableViewCellAccessory.Checkmark;
else
nativeCell.Accessory = UITableViewCellAccessory.None;
}
}
For reference here's the XAML where it is used:
<TableSection>
<local:CheckedTextCell Text="{Binding [6].Name}" IsChecked="{Binding [6].IsSelected}" Tapped="atiSelectValue" />
<local:CheckedTextCell Text="{Binding [7].Name}" IsChecked="{Binding [7].IsSelected}" Tapped="atiSelectValue" />
<local:CheckedTextCell Text="{Binding [8].Name}" IsChecked="{Binding [8].IsSelected}" Tapped="atiSelectValue" />
</TableSection>
Does anyone have any ideas how can I implement this in Android using a custom renderer or if it is even possible to do it?
Here's an example (not mine) of what it looks like in iOS. What I am hoping for is the Android can show a similar tick mark on the right side.
The Label view is used for displaying text, both single and multi-line. Labels can have text decorations, colored text, and use custom fonts (families, sizes, and options).
Despite there already being an answer, the solution I found allows you to choose which borders you specifically want to show and how much. Show activity on this post. In xamarin forms shared project's xaml file use ExLabel instead of Label , you will see a border on it.
Gets a value that indicates whether the cell has at least one menu item in its ContextActions list property. (Inherited from Cell)
You can build a custom renderer in Android (although, I think an easier approach is to create a custom ViewCell
):
using System.ComponentModel;
using Android.Content;
using Android.Views;
using Android.Widget;
using Sof;
using Sof.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using AView = Android.Views.View;
[assembly: ExportRenderer(typeof(ExtCheckedTextCell), typeof(ExtCheckedTextCellRenderer))]
namespace Sof.Droid
{
public class ExtCheckedTextCellRenderer : TextCellRenderer
{
public const string CheckedText = "✓";
private TextView Check { get; set; }
protected override AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context)
{
var view = base.GetCellCore(item, convertView, parent, context) as BaseCellView;
if (this.Check == null)
{
this.Check = new TextView(context);
this.Check.Gravity = GravityFlags.Center;
using (var lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.MatchParent))
{
view.AddView(this.Check, lp);
}
var paddingRight = context.Resources.GetDimension(Resource.Dimension.abc_list_item_padding_horizontal_material);
view.SetPadding(view.PaddingLeft, view.PaddingTop, (int)paddingRight, view.PaddingBottom);
}
return view;
}
protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args)
{
base.OnCellPropertyChanged(sender, args);
if (args.PropertyName.Equals(ExtCheckedTextCell.IsCheckedProperty.PropertyName) &&
sender is ExtCheckedTextCell extCheckedTextCell && this.Check != null)
{
this.Check.Text = extCheckedTextCell.IsChecked ? CheckedText : string.Empty;
}
}
}
}
For a simple layout like you want (label and checkmark), a custom ViewCell
seems more appropriate and allows direct control over the style.
ExtCheckedTextCell2.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Sof.ExtCheckedTextCell2"
x:Name="this">
<ViewCell.View>
<StackLayout Orientation="Horizontal"
Padding="12, 0">
<Label HorizontalOptions="FillAndExpand"
Text="{Binding Text, Source={x:Reference this}}"
VerticalTextAlignment="Center" />
<Label IsVisible="{Binding IsChecked, Source={x:Reference this}}"
HorizontalOptions="End"
Text="✓"
VerticalTextAlignment="Center"/>
</StackLayout>
</ViewCell.View>
</ViewCell>
ExtCheckedTextCell2.xaml.cs
public partial class ExtCheckedTextCell2 : ViewCell
{
public static readonly BindableProperty IsCheckedProperty =
BindableProperty.Create(
nameof(IsChecked),
typeof(bool),
typeof(ExtCheckedTextCell2),
default(bool));
public static readonly BindableProperty TextProperty =
BindableProperty.Create(
nameof(Text),
typeof(string),
typeof(ExtCheckedTextCell2),
default(string));
public ExtCheckedTextCell2()
{
InitializeComponent();
}
public bool IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
protected override void OnTapped()
{
base.OnTapped();
this.IsChecked = !this.IsChecked;
}
}
<TableView>
<TableSection Title="Custom Renderer">
<local:ExtCheckedTextCell Text="Test1" Tapped="Handle_Tapped" />
<local:ExtCheckedTextCell Text="Test2" Tapped="Handle_Tapped" />
<local:ExtCheckedTextCell Text="Test3" Tapped="Handle_Tapped" />
</TableSection>
<TableSection Title="Custom Xamarin.Forms ViewCell">
<local:ExtCheckedTextCell2 Text="Test1" />
<local:ExtCheckedTextCell2 Text="Test2" />
<local:ExtCheckedTextCell2 Text="Test3" />
</TableSection>
</TableView>
But you can also do it in xaml ?
This is a xaml only solution :) should work for Android and Ios .
.xaml
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StackoverflowQ.Views.MainPage"
Title="Driving & Navigation">
<ContentPage.Resources>
</ContentPage.Resources>
<ScrollView>
<StackLayout>
<StackLayout x:Name="Header" BackgroundColor="#efeff4" HorizontalOptions="FillAndExpand" HeightRequest="30" Padding="10">
<Label Text="NAVIGATION VOICE VOLUME" Margin="0, 0, 0, 5" VerticalOptions="EndAndExpand" />
</StackLayout>
<StackLayout Orientation="Horizontal" Padding="10">
<Label Text="No Voice" TextColor="Black" />
<Image Source="checkboxchecker.png" IsVisible="{Binding IsCheckBoxVisible}" HorizontalOptions="EndAndExpand" />
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding TapCheckBoxCommand}" NumberOfTapsRequired="1" />
</StackLayout.GestureRecognizers>
</StackLayout>
<BoxView HeightRequest="1" HorizontalOptions="FillAndExpand" BackgroundColor="#efeff4" />
</StackLayout>
</ScrollView>
</ContentPage>
ViewModel
namespace StackoverflowQ.ViewModels
{
public class MainPageViewModel : ViewModelBase
{
public DelegateCommand TapCheckBoxCommand { get; set; }
private bool _isCheckBoxVisible;
public bool IsCheckBoxVisible
{
get => _isCheckBoxVisible;
set => SetProperty(ref _isCheckBoxVisible, value);
}
public MainPageViewModel(INavigationService navigationService)
: base(navigationService)
{
Title = "Main Page";
TapCheckBoxCommand = new DelegateCommand(TapCheckBoxSelected);
}
public void TapCheckBoxSelected()
{
IsCheckBoxVisible = !IsCheckBoxVisible;
}
}
}
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