Orange selected ListView item highlighted in MAUI

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.

An example of the issue with a ListView - Orange selected ListView item highlighted in MAUI
An example of the issue with a ListView

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>
enter image description here

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.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.