如何通过自定义渲染器独立设置Xamarin.Forms ListView选中项颜色
用自定义渲染器为Xamarin.Forms ListView单独设置选中项颜色
当然可以用自定义渲染器搞定这个需求!这绝对是比全局改styles.xml或者投机取巧修改单元格背景更靠谱的原生方案,还能给不同的ListView单独配置选中项颜色,完美满足你的精细化需求~
实现思路
我们需要先在共享项目中创建一个带自定义属性的ListView子类,然后针对Android和iOS平台分别编写自定义渲染器,将自定义属性映射到原生控件的选中样式上。
步骤1:创建自定义ListView(共享项目)
先定义一个继承自ListView的类,添加一个绑定属性用来指定选中项颜色:
using Xamarin.Forms; namespace YourAppNamespace { public class CustomListView : ListView { // 定义选中项颜色的绑定属性 public static readonly BindableProperty SelectedItemColorProperty = BindableProperty.Create( nameof(SelectedItemColor), typeof(Color), typeof(CustomListView), Color.Default); public Color SelectedItemColor { get => (Color)GetValue(SelectedItemColorProperty); set => SetValue(SelectedItemColorProperty, value); } } }
步骤2:Android平台自定义渲染器
在Android项目中编写渲染器,将自定义颜色映射到原生ListView的选中选择器:
using Android.Content; using Android.Graphics.Drawables; using YourAppNamespace; using YourAppNamespace.Droid; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(CustomListView), typeof(CustomListViewRenderer))] namespace YourAppNamespace.Droid { public class CustomListViewRenderer : ListViewRenderer { public CustomListViewRenderer(Context context) : base(context) { } protected override void OnElementChanged(ElementChangedEventArgs<ListView> e) { base.OnElementChanged(e); if (Control != null && e.NewElement is CustomListView customListView) { // 设置ListView的选择模式(这里以单选为例,多选可调整为ChoiceMode.Multiple) Control.ChoiceMode = Android.Widget.ChoiceMode.Single; // 将Xamarin.Forms颜色转换为Android颜色,创建选中背景Drawable var androidColor = customListView.SelectedItemColor.ToAndroid(); var selectedDrawable = new ColorDrawable(androidColor); // 给原生ListView设置选中选择器 Control.ListSelector = selectedDrawable; } } } }
步骤3:iOS平台自定义渲染器
在iOS项目中,我们需要为每个UITableViewCell设置选中时的背景视图,注意要处理单元格复用的情况:
using UIKit; using YourAppNamespace; using YourAppNamespace.iOS; using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; [assembly: ExportRenderer(typeof(CustomListView), typeof(CustomListViewRenderer))] namespace YourAppNamespace.iOS { public class CustomListViewRenderer : ListViewRenderer { protected override void OnElementChanged(ElementChangedEventArgs<ListView> e) { base.OnElementChanged(e); } // 重写GetCell方法,确保复用的单元格也能正确应用选中样式 public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv) { var cell = base.GetCell(item, reusableCell, tv); var customListView = Element as CustomListView; if (customListView != null && cell != null) { // 将Xamarin.Forms颜色转换为iOS颜色,设置选中背景视图 var iosColor = customListView.SelectedItemColor.ToUIColor(); cell.SelectedBackgroundView = new UIView { BackgroundColor = iosColor }; } return cell; } } }
步骤4:在XAML中使用自定义ListView
现在你可以在XAML中直接使用CustomListView,给不同的实例设置不同的选中颜色:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:YourAppNamespace" x:Class="YourAppNamespace.MainPage"> <StackLayout Padding="10"> <!-- 第一个ListView:选中项为蓝色 --> <local:CustomListView SelectedItemColor="Blue" ItemsSource="{Binding FirstListItems}" Margin="0 0 0 20"> <local:CustomListView.ItemTemplate> <DataTemplate> <TextCell Text="{Binding .}" /> </DataTemplate> </local:CustomListView.ItemTemplate> </local:CustomListView> <!-- 第二个ListView:选中项为深绿色 --> <local:CustomListView SelectedItemColor="#2E7D32" ItemsSource="{Binding SecondListItems}"> <local:CustomListView.ItemTemplate> <DataTemplate> <TextCell Text="{Binding .}" /> </DataTemplate> </local:CustomListView.ItemTemplate> </local:CustomListView> </StackLayout> </ContentPage>
注意事项
- 如果之前尝试的方案出现多个单元格异常,大概率是没有处理iOS单元格复用的状态残留,上面的iOS渲染器通过重写
GetCell方法,确保每个复用的单元格都能正确设置选中背景,避免这类问题。 - Android平台如果需要更复杂的选中状态(比如选中时带边框、渐变),可以创建
StateListDrawable来替代简单的ColorDrawable。
内容的提问来源于stack exchange,提问作者Trevi Awater
相关产品推荐
相关产品推荐

