Advertisement
Advertisement

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?

Advertisement

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.

Advertisement

By Enrico

My greatest passion is technology. I am interested in multiple fields and I have a lot of experience in software design and development. I started professional development when I was 6 years. Today I am a strong full-stack .NET developer (C#, Xamarin, Azure)

Leave a Reply

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

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.