Xamarin Forms - Change a ListView's Selected Item Colour
(Update 2018-10-02)
Hey folks, I’m sorry but the latest versions of Xamarin Forms (> 2.5 I think) seem to have broken everything around this, and this solution no longer works. There’s a little more information in the comments below, along with some work I did, specifically: http://disq.us/p/1srl4w8, but that’s as far as I managed to get.
I recently had to set the colour for a Xamarin Forms ListView’s SelectedItem
to something other than the default. This was primarily because the colour scheme for the app I was building on iOS didn’t play nice with the selected-item highlight when it was tapped.
This was actually a little bit more work than I thought it would be (since there’s no ‘SelectedItemColor’ property).
ListView items are based on Cell
-derived classes like ViewCell
and TextCell
, and so it’s not actually the ListView’s responsibility to handle the colour change. It’s up to the Cell-based object to do that itself. I guess they could have made it a little easier by creating a ‘SelectedBackgroundColour’ (or similar) property. But given how simple it is to implement, it’s actually not that big a deal.
The important thing to take away from this is that it’s NOT the ListView you’re modifying, it’s the Cell-based object (embedded in the ListView item’s DataTemplate
) which needs to change. The ListView will happily pass on the fact that something has been (un)selected, but leaves it up to the developer to handle what happens when it is.
There was a quick and dirty Android-only solution, which was to set a couple of styles in the Android Resources
folder, but (a) this was an Android-only solution (and I need it to work on iOS as well), and (b) by setting the style of pressed and highlighted items, it changed it for ALL controls which used that style. Suddenly ALL my (Android) Xamarin Forms ListViews had the same selected colour, and everything else I touched, tapped or long-pressed had that colour too.
There’s a couple of other examples in that thread which show how to react to the ItemTapped
and/or ItemSelected
events. But they struck me as a little clunky, mainly because they’d have to be done manually and individually for every ListView.
However, a little bit more digging through that thread led me to an example using a custom renderer and a CustomTextCell
.
Since all I needed to do was change the background colour of the ViewCell
in my ListView when it was selected, and then reset it back once it was deselected, it was pretty painless to port it over.
Here’s the code:
Original ListView Item DataTemplate
Before changes, it looked something like this (bog-standard ViewCell, nothing special. However the ListView it’s contained in had to have a background colour of Black
because reasons):
Note that on iOS, you can’t tell when an item is selected…
On Android, you can, but the shocking orange default colour is a bit offensive…
Let’s fix it with a custom renderer.
Custom ViewCell XAML ‘placeholder’ control
This guy just inherits directly from a ViewCell
and adds a single BindableProperty
so we can hook up the colour we’d like to use when the item is selected.
Android custom renderer
As the cell is rendered, this one captures the current (unselected, default theme) colour of the Android view cell, and then sets the colour of the view-cell’s background whenever the IsSelected
property of the Android view-cell changes from false to true. And then resets it to the originally captured colour when when it flips back.
Obviously this may get a little more complex if you need to select multiple items in your list, but this is as far as I needed to go for my solution.
Note that this set/reset code will run every time you (de)select and item in the list.
iOS custom renderer
It doesn’t get much simpler than this one. The cool thing about the iOS implementation is that it sets the selected colour as a property of the cell as it’s being constructed. Once it’s done, the UI doesn’t need to come back to ‘ask’ the custom renderer what colour it should change to (unlike the Android one, above).
After dropping in the ExtendedViewCell
to replace the original ViewCell
, and setting the SelectedBackgroundColor
to Teal
:
How does it look now?
iOS
apologies for the janky iOS screen caps, I was using the iOS simulator over a very poor, long distance wifi connection
Android
There’s a simple Xamarin Forms project over in GitHub so you can try it out for yourself. As usual it’s published under the MIT licence, so you can do what you like with the code.