This project you can find at: https://github.com/officialdoniald/Xamarin.Forms.ChangeListviewSelectedColor
We have to create a Custom Renderer for a ViewCell. So let’s create a class in the .NET Standard,/PCL Project:
https://github.com/officialdoniald/Xamarin.Forms.ChangeListviewSelectedColor/tree/master/Xamarin.Forms.ChangeLvSelectedColor/Xamarin.Forms.ChangeLvSelectedColor/CustomControl/ListViewCustomViewCell.cs/
We created a property for the SelectedItem’s color. Don’t forget: this enum is a cutom enum, we have to create it:
Let’s create the platform specific code.
Android: we have to change the Android’s Theme at runtime via EventHandler.
We have to create a ViewCellRenderer class ( https://github.com/officialdoniald/Xamarin.Forms.ChangeListviewSelectedColor/blob/master/Xamarin.Forms.ChangeLvSelectedColor/Xamarin.Forms.ChangeLvSelectedColor.Android/CustomRenderers/CustomViewCellRenderer.cs ):
using System.ComponentModel; using Android.Content; using Android.Views; using Xamarin.Forms; using Xamarin.Forms.ChangeLvSelectedColor.CustomControl.ListView; using Xamarin.Forms.ChangeLvSelectedColor.Droid.CustomRenderers; using Xamarin.Forms.ChangeLvSelectedColor.Helper; using Xamarin.Forms.Platform.Android; using static Xamarin.Forms.ChangeLvSelectedColor.Droid.MainActivity; [assembly: ExportRenderer(typeof(CustomViewCell), typeof(CustomViewCellRenderer))] namespace Xamarin.Forms.ChangeLvSelectedColor.Droid.CustomRenderers { public class CustomViewCellRenderer : ViewCellRenderer { protected override global::Android.Views.View GetCellCore(Cell item, global::Android.Views.View convertView, ViewGroup parent, Context context) { var _cellCore = base.GetCellCore(item, convertView, parent, context); return _cellCore; } protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args) { base.OnCellPropertyChanged(sender, args); var extendedViewCell = (CustomViewCell)sender; if (extendedViewCell.SelectedCellColor == ListViewSelectedBackGroundColor.CianBlue) { AndroidEvents.OnAndroidThemeChangeNeeded_Event(null, Xamarin.Forms.ChangeLvSelectedColor.Droid.Resource.Style.MainCianBlueTheme); } else if (extendedViewCell.SelectedCellColor == ListViewSelectedBackGroundColor.Normal) { AndroidEvents.OnAndroidThemeChangeNeeded_Event(null, Xamarin.Forms.ChangeLvSelectedColor.Droid.Resource.Style.MainTheme); } else if (extendedViewCell.SelectedCellColor == ListViewSelectedBackGroundColor.Transparent) { AndroidEvents.OnAndroidThemeChangeNeeded_Event(null, Xamarin.Forms.ChangeLvSelectedColor.Droid.Resource.Style.MainTransparentTheme); } } } }
AndroidEvents is a static class, and in this class we have to create an event ( https://github.com/officialdoniald/Xamarin.Forms.ChangeListviewSelectedColor/blob/master/Xamarin.Forms.ChangeLvSelectedColor/Xamarin.Forms.ChangeLvSelectedColor.Android/MainActivity.cs ):
public class AndroidEvents { public static event EventHandlerOnAndroidThemeChangeNeeded; public static void OnAndroidThemeChangeNeeded_Event(object sender, int id) { OnAndroidThemeChangeNeeded?.Invoke(sender, id); } }
This event invoke the Theme Changing at runtime. We have to call it, when the user interact with the ListView(ViewCell). We have to subscribe on this event in the MainActivity:
protected override void OnCreate(Bundle savedInstanceState) { TabLayoutResource = Resource.Layout.Tabbar; ToolbarResource = Resource.Layout.Toolbar; base.OnCreate(savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); AndroidEvents.OnAndroidThemeChangeNeeded += AndroidEvents_OnAndroidThemeChangeNeeded; ; LoadApplication(new App()); } private void AndroidEvents_OnAndroidThemeChangeNeeded(object sender, int themeid) { RunOnUiThread(() => { SetTheme(themeid); }); }
Finally, we have to create the Theme Shema in the style.xml (MainCianBlueTheme and MainTransparentTheme):
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MainTheme" parent="MainTheme.Base">
</style>
<style name="MainCianBlueTheme" parent="MainCianBlueTheme.Base">
</style>
<style name="MainTransparentTheme" parent="MainTransparentTheme.Base">
</style>
<!-- Base theme applied no matter what API -->
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<!--If you are using revision 22.1 please use just windowNoTitle. Without android:-->
<item name="windowNoTitle">true</item>
<!--We will be using the toolbar so no need to show ActionBar-->
<item name="windowActionBar">false</item>
<!-- Set theme colors from http://www.google.com/design/spec/style/color.html#color-color-palette -->
<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">#2196F3</item>
<!-- colorPrimaryDark is used for the status bar -->
<item name="colorPrimaryDark">#1976D2</item>
<!-- colorAccent is used as the default value for colorControlActivated
which is used to tint widgets -->
<item name="colorAccent">#FF4081</item>
<!-- You can also set colorControlNormal, colorControlActivated
colorControlHighlight and colorSwitchThumbNormal. -->
<item name="windowActionModeOverlay">true</item>
<item name="android:datePickerDialogTheme">@style/AppCompatDialogStyle</item>
</style>
<style name="MainCianBlueTheme.Base" parent="MainTheme">
<item name="android:colorPressedHighlight">@color/anlistviewSelection</item>
<item name="android:colorLongPressedHighlight">@color/anlistviewSelection</item>
<item name="android:colorFocusedHighlight">@color/anlistviewSelection</item>
<item name="android:colorActivatedHighlight">@color/anlistviewSelection</item>
<item name="android:activatedBackgroundIndicator">@color/anlistviewSelection</item>
</style>
<style name="MainTransparentTheme.Base" parent="MainTheme">
<item name="android:colorPressedHighlight">@color/transparentlistviewSelection</item>
<item name="android:colorLongPressedHighlight">@color/transparentlistviewSelection</item>
<item name="android:colorFocusedHighlight">@color/transparentlistviewSelection</item>
<item name="android:colorActivatedHighlight">@color/transparentlistviewSelection</item>
<item name="android:activatedBackgroundIndicator">@color/transparentlistviewSelection</item>
</style>
<style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog">
<item name="colorAccent">#FF4081</item>
</style>
</resources>
and their @color variablesin the colors.xml (listviewSelection, anlistviewSelection, transparentlistviewSelection):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="launcher_background">#FFFFFF</color>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="listviewSelection">#f17a0a</color>
<color name="anlistviewSelection">#40E0D0</color>
<color name="transparentlistviewSelection">#00000000</color>
</resources>
iOS: we just have to create a platform specific version of the CustomViewCell class, and gain two properties a color (https://github.com/officialdoniald/Xamarin.Forms.ChangeListviewSelectedColor/blob/master/Xamarin.Forms.ChangeLvSelectedColor/Xamarin.Forms.ChangeLvSelectedColor.iOS/CustomRenderer/CustomViewCellRenderer.cs):
using UIKit; using Xamarin.Forms; using Xamarin.Forms.ChangeLvSelectedColor.CustomControl.ListView; using Xamarin.Forms.ChangeLvSelectedColor.iOS.CustomRenderer; using Xamarin.Forms.Platform.iOS; [assembly: ExportRenderer(typeof(CustomViewCell), typeof(CustomViewCellRenderer))] namespace Xamarin.Forms.ChangeLvSelectedColor.iOS.CustomRenderer { public class CustomViewCellRenderer : ViewCellRenderer { public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv) { var customViewCell = (CustomViewCell)item; var cell = base.GetCell(item, reusableCell, tv); cell.SelectedBackgroundView = new UIView { BackgroundColor = GetColor(customViewCell.SelectedCellColor) }; //You can define a new property in the CustomViewCell class, and you can use it here: //This code is set the unselected background color of the ViewCell: //cell.BackgroundColor = GetColor(customViewCell.UnSelectedCellColor); return cell; } public UIColor GetColor(Helper.ListViewSelectedBackGroundColor color) { switch (color) { case Helper.ListViewSelectedBackGroundColor.CianBlue: return Color.FromHex("#40E0D0").ToUIColor(); default: return Color.Transparent.ToUIColor(); } } } }