(I asked on the Xamarin forums but didn't get a response, so I'm trying here)
In Xamarin Forms, setting BackgroundColor
in a ListView ItemTemplate
causes haptic-feedback to be disabled.
Is there any way around this? I'd like to customize the colors of my list-items, but not having haptic feedback looks like garbage.
Example 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>
The closest I've gotten is changing the BackgroundColor
in ViewCell.Tapped
, then changing it back in View.OnAppearing()
(ViewCell.Appearing
is broken), but that changes the background when the finger is lifted, rather than when it's pressed.
I'm testing on Android but would prefer a cross-platform solution.
Check your post on the Xamarin forum for my feedback. I have an easy drop-in solution for you called XFGloss. Its a free open source add-on for Xamarin.Forms. The source is available on GitHub. There is also a NuGet package available. It allows you to assign a BackgroundColor value to the standard XF cell controls (TextCell, EntryCell, etc.). There are several other new properties also added by XFGloss.
If you prefer to fix your existing implementation, you can review the changes I made to support the visual feedback in this code commit.
Once you set the Background color then you won't get to see the selected item color or Haptic feedback unless you create a custom render on each platform.
Here is the work around you can implement which is cross platform and MVVM based using Bindings for setting the color of selected item:
SelectedItem
of ListView
. StackLayout
to an auto property and set the value of "#CCCCCC" if its not selected item else some other color. MyItem
class and invoke OnPropertyChanged
of BackgroundColor property. For this you can raise an event and subscribe or anything that you feel comfortable.(this is not implemented in the sample pseudo code provided below) ViewModel :
public class MyViewModel : IMyViewModel
{
public ObserveableCollection<MyItem> Items { get; set; }
public MyItem SelectedMyItem { get; set; }
}
List item class :
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>
Haptic feedback work around :
Usually a touch is 200-300ms. Once an item is tapped you can change the color of the background for that much duration and then set to the original color.
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
}
You can even improve this further by trying to incorporate animations, maybe the FadeTo for changing colors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With