这是我到目前为止为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); }
}
}
}
我的渲染器如下所示:
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;
}
}
作为参考,这里是使用XAML的地方:
<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>
有没有人知道如何使用自定义渲染器在Android中实现它,或者甚至有可能实现?
这是一个iOS外观的示例(不是我的)。我希望Android可以在右侧显示类似的刻度线。
答案 0 :(得分:3)
但是您也可以使用xaml吗?
这是仅适用于xaml的解决方案:)应该适用于Android和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;
}
}
}
答案 1 :(得分:3)
您可以在Android中构建自定义渲染器(尽管我认为更简单的方法是创建自定义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;
}
}
}
}
对于您想要的简单布局(标签和选中标记),自定义ViewCell
似乎更合适,并且可以直接控制样式。
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>