Можно ли изменить цвет фона в ячейках ListView без потери тактильной (сенсорной) обратной связи?

(я спросил на форумах Xamarin, но не получил ответа, поэтому я пробую здесь)

В Xamarin Forms установка BackgroundColor в ListView ItemTemplate приводит к отключению гапловой обратной связи.

Есть ли способ обойти это? Я хотел бы настроить цвета моих элементов списка, но отсутствие тактильной обратной связи выглядит как мусор.

Пример XAML:

 <ListView x:Name="list"
           ItemTapped="OnItemSelected"
           IsGroupingEnabled="True"
           GroupDisplayBinding="{Binding Key}"
           GroupShortNameBinding="{Binding Key}"
           HasUnevenRows="True"
           ItemsSource="{Binding .}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
              <StackLayout VerticalOptions="FillAndExpand"
                           Padding="5, 20"
                           BackgroundColor="#CCCCCC"> <!--This line causes haptic feedback to fail -->
                <Label Text="{Binding Name}"
                       TextColor="Black"
                       VerticalOptions="Center"
                       FontSize="Large"/>
              </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Самое близкое, что я получил, это изменить BackgroundColor в ViewCell.Tapped, а затем вернуть его обратно в View.OnAppearing() (ViewCell.Appearing), но это изменит фон, когда палец поднят, а не когда он нажал.

Я тестирую Android, но предпочитаю кросс-платформенное решение.

Ответ 1

Проверяйте свой пост на форуме Xamarin для моей обратной связи. У меня есть простое решение для вас, которое вы назвали XFGloss. Это бесплатное дополнение с открытым исходным кодом для Xamarin.Forms. Источник доступен на GitHub. Существует также пакет NuGet. Он позволяет назначить значение BackgroundColor для стандартных элементов управления XF (TextCell, EntryCell и т.д.). Есть еще несколько новых свойств, добавленных XFGloss.

Если вы предпочитаете исправлять свою существующую реализацию, вы можете просмотреть изменения, которые я сделал для поддержки визуальной обратной связи в этом коммитае.

Ответ 2

Как только вы установите цвет фона, вы не сможете увидеть выбранный цвет элемента или обратную связь, если вы не создадите собственный рендер на каждой платформе.

Вот работа, которую вы можете реализовать, которая представляет собой кросс-платформу и MVVM на основе Bindings для установки цвета выбранного элемента:

  • Привязать свойство к SelectedItem от ListView.
  • Привяжите цвет фона вашего StackLayout к свойству auto и установите значение "#CCCCCC", если его выбранный элемент еще не имеет другого цвета.
  • Вам нужно подписаться на свойство SelectedMyItem в классе MyItem и вызвать OnPropertyChanged свойства BackgroundColor. Для этого вы можете поднять мероприятие и подписаться или что-нибудь, что вам удобно. (Это не реализовано в приведенном ниже примере псевдо-кода)

ViewModel:

public class MyViewModel : IMyViewModel
{
    public ObserveableCollection<MyItem> Items { get; set; }
    public MyItem SelectedMyItem { get; set; }
}

Класс элемента списка:

public class MyItem 
{
    private readonly IMyViewModel _myViewModel;

    public MyItem(IMyViewModel myViewModel)
    {
        _myViewModel = myViewModel;
    }

    public string Name { get; set; }
    public Color BackgroundColor => _myViewModel.SelectedMyItem == this 
                                    ? Color.Red : Color.FromHex("CCCCCC");        
}

XAML:

<ListView x:Name="list"
           IsGroupingEnabled="True"
           GroupDisplayBinding="{Binding Key}"
           GroupShortNameBinding="{Binding Key}"
           HasUnevenRows="True"
           ItemsSource="{Binding Items}"
           SelectedItem="{Binding SelectedMyItem}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
              <StackLayout VerticalOptions="FillAndExpand"
                           Padding="5, 20"
                           BackgroundColor="{Binding BackgroundColor}">
                   <StackLayout.GestureRecognizers>
                       <TapGestureRecognizer Tapped="OnItemTapped" />
                   </StackLayout.GestureRecognizers>
                <Label Text="{Binding Name}"
                       TextColor="Black"
                       VerticalOptions="Center"
                       FontSize="Large"/>
              </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Взаимная обратная связь работает:

Обычно прикосновение составляет 200-300 мс. После того, как элемент используется, вы можете изменить цвет фона для этой продолжительности, а затем установить исходный цвет.

public async void OnItemTapped(object sender, EventArgs args) 
{
   BackgroundColor = Color.Orange; //touch color
   await Task.Delay(250);          //time to show new color
   BackgroundColor = Color.Red;    //original color
}

Вы даже можете улучшить это, пытаясь включить animations, возможно, FadeTo для изменения цветов.

Ответ 3

Вы можете просто использовать это в унаследованном классе Viewcell,

this.Tapped += ViewCell_Tapped;//Используя постукивание в вашей ячейке просмотра, вы можете достигнуть, как и тактильный.

закрытый async void ViewCell_Tapped (отправитель объекта, EventArgs e)         {             this.View.BackgroundColor = Color.Gray;             ждать Task.Delay(10);
            this.View.BackgroundColor = Color.White;         }

Это работает для меня.