Working on my new MAUI project called Language In Use, I face a funny issue with the orange item in a ListView when an item is selected or highlighted. I was asking this question in the past and the answer I got was that this was a bug, and it will be fixed with the NET8.
With the new version of the framework, the issue is still there. When I run my NET8
MAUI
app on an Android device, ListView
displays the list of items correctly. When I tap on an item, the background is an orange colour, as you see in the following screenshot.
Is a way to change the color of the selected item in a ListView
?
A suggestion (that didn’t work for me)
I saw a few people refer to this solution but it didn’t work for me. I reported it just in case it could be one possible answer. Please let me know if it works for you.
Under the Android
folder, I added a new XML file called style.xml and set the property to AndroidResource
. The content of this file is
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Test.MainTheme" parent="Maui.SplashTheme">
<item name="android:colorActivatedHighlight">
@android:color/transparent
</item>
</style>
</resources>
Then, I change the MainActivity.cs
in particular, the theme as instructed.
[Activity(Theme = "@style/Test.MainTheme", MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation |
ConfigChanges.UiMode | ConfigChanges.ScreenLayout |
ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
The solution
So, after looking around a lot and opening posts on Stackoverflow and GitHub, I found the solution that is coming from Kenji Nagano in this post on GitHub.
First, this to check is if ListView
you set the CachingStrategy
and in particular CachingStrategy="RecycleElement"
. If so, remove it. Then, the following solution will work.
The first step, add CustomViewCell.cs
to your project folder.
public class CustomViewCell : Microsoft.Maui.Controls.ViewCell
{
public static readonly BindableProperty SelectedBackgroundColorProperty =
BindableProperty.Create(
nameof(SelectedBackgroundColor), typeof(Color),
typeof(CustomViewCell), Colors.White);
public Color SelectedBackgroundColor
{
get { return (Color)GetValue(SelectedBackgroundColorProperty); }
set { SetValue(SelectedBackgroundColorProperty, value); }
}
public CustomViewCell()
{
}
}
Android implementation
Then, in Platforms/Android
folder, create the platform-specific implementation file CustomViewCellHandler.cs
:
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
using Android.Graphics.Drawables;
using AContext = Android.Content.Context;
using AView = Android.Views.View;
using AViewGroup = Android.Views.ViewGroup;
using Microsoft.Maui.Controls.Platform;
namespace MauiAppListViewTest.Platforms.Android
{
public class CustomViewCellHandler :
Microsoft.Maui.Controls.Handlers.Compatibility.ViewCellRenderer
{
private AView pCellCore;
private bool pSelected;
private Drawable pUnselectedBackground;
protected override AView GetCellCore(Cell item, AView convertView,
AViewGroup parent, AContext context)
{
pCellCore = base.GetCellCore(item, convertView, parent, context);
this.pSelected = false;
this.pUnselectedBackground = pCellCore.Background;
return pCellCore;
}
protected override void OnCellPropertyChanged(object sender,
System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnCellPropertyChanged(sender, e);
if (e.PropertyName == "IsSelected")
{
pSelected = !(pSelected);
if (pSelected)
{
pCellCore.SetBackgroundColor(
((CustomViewCell)sender).SelectedBackgroundColor.ToAndroid());
}
else
{
pCellCore.SetBackground(this.pUnselectedBackground);
}
}
}
}
}
Now, register your handler like below in the MauiProgram.cs
:
#if ANDROID
using MauiAppListViewTest.Platforms.Android;
#endif
namespace MauiAppListViewTest
{
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
<!--Omitted for brevity-->
.ConfigureMauiHandlers(handlers => {
#if ANDROID
handlers.AddHandler<CustomViewCell, CustomViewCellHandler>();
#endif
});
Don’t forget to setting SelectedBackgroundColor="Green"
in XAML:
<ListView x:Name="lvTest" >
<ListView.ItemTemplate>
<DataTemplate>
<local:CustomViewCell SelectedBackgroundColor="Green" >
<Grid HeightRequest="44">
<Label Text="{Binding ItemName}" VerticalOptions="Center"/>
</Grid>
</local:CustomViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
iOS implementation
Then, in Platforms/
iOS folder, create the platform-specific implementation file CustomViewCellHandler.cs
:
public class CustomViewCellHandler : ViewCellRenderer
{
public override UITableViewCell GetCell(
Cell item, UITableViewCell reusableCell, UITableView tv)
{
var cell = base.GetCell(item, reusableCell, tv);
cell.SelectedBackgroundView = new UIView
{
BackgroundColor = ((CustomViewCell)item).SelectedBackgroundColor.ToPlatform()
};
return cell;
}
}
Again, I have to set the handle in the MauiProgram.cs
like
#if IOS
using MauiAppListViewTest.Platforms.iOS;
#endif
namespace MauiAppListViewTest
{
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
<!--Omitted for brevity-->
.ConfigureMauiHandlers(handlers => {
#if IOS
handlers.AddHandler<CustomViewCell, CustomViewCellHandler>();
#endif
});
Wrap up
In this post, I show the code I used when you add a ListView
in your project and an item highlighted in MAUI, its background is in orange. I hope this code can help you. Please let me know your thoughts in the comments or the forum.