Reputation: 1513
I'm having trouble with XF listview and custom renderer. I need to:
I've been able to change background color of selected item and everything is working unless I pre-select an item.
For the custom control and renderers I used the "standard" code found in many examples:
Custom control:
public class RRViewCell : ViewCell
{
public static readonly BindableProperty SelectedItemBackgroundColorProperty = BindableProperty.Create("SelectedItemBackgroundColor", typeof(Color), typeof(RRViewCell), Color.Default);
public Color SelectedItemBackgroundColor
{
get { return (Color)GetValue(SelectedItemBackgroundColorProperty); }
set { SetValue(SelectedItemBackgroundColorProperty, value); }
}
}
Android renderer:
public class RRViewCellRendererAndroid : ViewCellRenderer
{
private Android.Views.View _cellCore;
private Drawable _unselectedBackground;
private bool _selected;
protected override Android.Views.View GetCellCore(Cell item, Android.Views.View convertView, ViewGroup parent, Context context)
{
_cellCore = base.GetCellCore(item, convertView, parent, context);
_selected = false;
_unselectedBackground = _cellCore.Background;
return _cellCore;
}
protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args)
{
base.OnCellPropertyChanged(sender, args);
if (args.PropertyName == "IsSelected")
{
_selected = !_selected;
if (_selected)
{
var extendedViewCell = sender as RRViewCell;
_cellCore.SetBackgroundColor(extendedViewCell.SelectedItemBackgroundColor.ToAndroid());
}
else
{
_cellCore.SetBackground(_unselectedBackground);
}
}
}
}
XAML:
<ctrl:RRViewCell SelectedItemBackgroundColor="{StaticResource NavigationPrimary}">
(NavigationPrimary is set to a shade of blue).
As I said, everything is working if no no items are selected programmatically, but if I do:
MyList.SelectedItem = loc[0];
this is the result:
(sensible data masked!)
In this case, defaut background color is used instead of custom one.
Moreover, if I tap another item, this happens:
Please note that:
Upvotes: 0
Views: 317
Reputation: 14956
In Android easiest way is edit under Resources\values
:
add this line inside styles.xml
:
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
...
<item name="android:colorActivatedHighlight">@color/ListViewSelected</item>
...
</style>
then add the color/ListViewSelected
inside colors.xml
:
<color name="ListViewSelected">#96BCE3</color>
The downside is that once set, all listviews will enable this effect
Upvotes: 0
Reputation: 9209
This can be very frustrating, but with a lot of Xamarin stuff its a case of thinking laterally, but there are many ways of achieving this.
I've achieved something similar by disabling the ListView in built selection process and instead have the selected item always selected programmatically and none of it is platform specific. By doing it this way I can also prevent user selection from having an effect if I am running a long process such as updating the list.
I set the ListView.SelectionMode
to None and instead have ListView.ItemTapped
trigger my selection code.
Each of my ListView source items has an IsSelected property, which is set whenever an item is selected for view.
I'm not changing the background colour of the ListView.Item, but instead I use a BoxView with a fixed background colour with it's IsVisible bound to IsSelected e.g.
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid RowSpacing="0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="100*"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="1" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30*"/>
</Grid.RowDefinitions>
<BoxView Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="6" BackgroundColor="{StaticResource Primary}" IsVisible="{Binding IsSelected}" />
<Label Grid.Column="1" Grid.Row="0" HorizontalTextAlignment="Center" VerticalOptions="Center" Text="{Binding Destination}"/>
<Label Grid.Column="2" Grid.Row="0" HorizontalTextAlignment="Start" VerticalOptions="Center" Text="{Binding Description}"/>
<Label Grid.Column="3" Grid.Row="0" HorizontalTextAlignment="End" HorizontalOptions="End" VerticalOptions="Center" Text="{Binding ScaledValue}" FontAttributes="Bold" FontSize="Medium" BackgroundColor="{Binding StoredValueDiffers, Converter={x:StaticResource StoredDiffersConverter}}"/>
<Label Grid.Column="4" Grid.Row="0" HorizontalTextAlignment="Start" VerticalOptions="Center" Text="{Binding Units}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
Because the BoxView is declared first it is in the lowest layer and the other components are drawn over it.
I guess that in your case you could use a non-Boolean value to show whether an item has been selected manually (on tapped), programmatically or not at all and then a converter would select your background colour.
I hope that this gives you some ideas.
Upvotes: 0