Icono del sitio Programando a medianoche

Colores del DatePicker de Xamarin Forms con Visual Material en Android

DatePicker

Los que trabajamos con Xamarin Forms o Xamarin Android (o con Android Studio) notamos que es sencillo cambiar los colores del diálogo del DatePicker, simplemente hay que agregar algunas líneas a nuestro archivo «styles.xml» del proyecto de Android, y podemos modificar los colores, de manera similar a esto:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="MyTheme" parent="MyTheme.Base">
</style>
<style name="MyTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:datePickerDialogTheme">@style/AppCompatDialogStyle</item>
</style>
<style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog">
    <item name="colorAccent">#2196F3</item>
</style>

En este caso estamos diciéndole a nuestro tema que, para el estilo del DatePicker, utilice «AppCompatDialogStyle», donde el color de resaltado queremos que sea el #2196F3.

Visual Material

Por otro lado, también deben conocer la propiedad Visual de (valga la redundancia) los elementos visuales, la cual nos permite cambiar su apariencia para que, por ejemplo, los controles de formulario tengan un estilo «Material Design» u otro definido por nosotros o un tercero.

Ahora bien, el problema es cuando queremos hacer ambas cosas, o sea, establecemos que nuestros controles tengan la visual de Material, pero necesitamos que el diálogo del DatePicker utilice un color personalizado, y no se vea así:

DatePicker y Visual Material

¿Cómo podemos hacer que nuestro diálogo del DatePicker tenga los colores que necesitamos cuando utilizamos el Visual Material? Después de mucho investigar me di cuenta que no se pueden cambiar los estilos de los controles que no tienen un Visual="Default" a través del styles.xml, lo que nos imposibilita hacer de forma sencilla esta tarea, pero después de revisar el código de Xamarin Forms encontré una manera de hacerlo que no fuera muy compleja: tenemos que implementar nuestro propio Renderer en el proyecto de Android.
La idea es no hacer un renderer desde cero sólo para poder cambiar el cólor de este diálogo, en su lugar vamos a heredar el propio de Xamarin Forms, pero creando nosotros el diálogo con el estilo deseado:

using Android.App;
using Android.Content;
using Xamarin.Forms;
using Xamarin.Forms.Material.Android;

[assembly: ExportRenderer(typeof(DatePicker), typeof(MiProyecto.Droid.Renderer.DatePickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
namespace MiProyecto.Droid.Renderer
{
    class DatePickerRenderer : MaterialDatePickerRenderer
    {
        public DatePickerRenderer(Context context) : base(context) { }

        protected override DatePickerDialog CreateDatePickerDialog(int year, int month, int day)
        {
            DatePicker view = Element;
            var dialog = new DatePickerDialog(Context, Resource.Style.AppCompatDialogStyle, (o, e) =>
             {
                 view.Date = e.Date;
                 ((IElementController)view).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
             }, year, month, day);

            return dialog;
        }
    }
}

Acá hay varios puntos a destacar: primero tenemos el atributo assembly, donde especificamos que es un Renderer que se va a utilizar en los controles DatePicker y que se va a utilizar con el Visual Material. También podemos marcar que, como dijimos antes, nuestra clase hereda de MaterialDatePickerRenderer, así cualquier cambio que pueda surgir en la librería de Xamarin, nuestro control la va a heredar. Por último, sobreescribimos el método CreateDatePickerDialog para crear nosotros el diálogo, utilizando el estilo llamado AppCompatDialogStyle.
Por supuesto ahora tenemos que definir ese estilo en styles.xml, lo cual podemos hacer de esta manera:

<style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog">
  <item name="android:datePickerStyle">#7cd2de</item>
  <item name="android:textColor">#7cd2de</item>
  <item name="colorControlHighlight">#15daf8</item>
  <item name="colorControlActivated">#7cd2de</item>
  <item name="colorPrimary">#7cd2de</item>
  <item name="colorPrimaryDark">#7cd2de</item>
  <item name="android:yearListSelectorColor">#7cd2de</item>
</style>
<style name="DatePickerDialogStyle" parent="@android:style/Widget.Material.Light.DatePicker">
  <item name="android:headerBackground">#7cd2de</item>
</style>

Con esto definimos un estilo para los diálogos, que lo llamamos «AppCompatDialogStyle», utilizando los colores que deseemos.
Ya con esto agregado, podemos compilar y ver el diálogo de nuestro DatePicker con los colores que elegimos:

Espero que esto les sea de utilidad.
¡Suerte!

Salir de la versión móvil