xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

SelectionMode None keep the highlighting and Ripple #3463

Open quentinR0bert opened 6 years ago

quentinR0bert commented 6 years ago

Description

When we set the SelectionMode to None, we still have the Highlighting color on iOS and the Ripple effect on android

Steps to Reproduce

  1. Set a ListView
  2. Set the SelectionMode to None
  3. Touch an Item

Expected Behavior

Nothing append

Actual Behavior

iOS : We see the Highlighting color Android : we see the Ripple effect

Basic Information

Keboo commented 6 years ago

I ran into this issue as well. For anyone else seeking a quick fix here is how I solved it for my app. Please note that I am not doing anything fancy with SelectionMode. For every ListView in my app it is set once and never changed.

iOS The initial PR #1801 indicates that this property should change the AllowsSelection on the UITableView. It appears that this detail was missed when the renderer was implemented.

Here is my iOS renderer.

public class ListViewRendererEx : ListViewRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
    {
        base.OnElementChanged(e);
        if (e.NewElement != null && Control != null)
        {
            UpdateSelectionMode();
        }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        switch (e.PropertyName)
        {
            case nameof(ListView.SelectionMode):
                UpdateSelectionMode();
                break;
        }
    }

    private void UpdateSelectionMode()
    {
        if (Element is ListView listView &&
            Control is UITableView tableView)
        {
            switch (listView.SelectionMode)
            {
                case ListViewSelectionMode.None:
                    tableView.AllowsSelection = false;
                    break;
                case ListViewSelectionMode.Single:
                    tableView.AllowsSelection = true;
                    break;
            }
        }
    }
}

Android On Android the ripple effect is controlled by the Selector drawable. To fix it in my app I simply replaced the drawable with a transparent color drawable. I am not confident this will work in all cases, but for my simplistic needs it solves the issue.

Here is my Android renderer.

public class ListViewRendererEx : ListViewRenderer
{
    private Drawable _SelectorDrawable;

    public ListViewRendererEx(Context context) 
        : base(context)
    { }

    protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
    {
        base.OnElementChanged(e);
        if (e.NewElement != null && Control != null)
        {
            UpdateSelectionMode();
        }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        switch (e.PropertyName)
        {
            case nameof(ListView.SelectionMode):
                UpdateSelectionMode();
                break;
        }
    }

    private void UpdateSelectionMode()
    {
        if (Element is ListView listView &&
            Control is Android.Widget.ListView droidListView)
        {
            switch (listView.SelectionMode)
            {
                case ListViewSelectionMode.None:
                    _SelectorDrawable = droidListView.Selector;
                    droidListView.Selector = new ColorDrawable(Color.Transparent);
                    break;
                case ListViewSelectionMode.Single:
                    if (_SelectorDrawable != null)
                    {
                        droidListView.Selector = _SelectorDrawable;
                    }
                    break;
            }
        }
    }
}
bares43 commented 5 years ago

Same issue for me...

quentinR0bert commented 5 years ago

We have a release date for this fix ? That we can remove the renderers and only use the framework

gtbuchanan commented 5 years ago

Related to #3156. The workaround for this on UWP is to set SelectionMode="None" and the legacy accessibility setting: :

InitializeComponent();
ListViewName.On<Windows>().SetSelectionMode(ListViewSelectionMode.Inaccessible);
quentinR0bert commented 4 years ago

No news after one Year ?