Twitter Facebook RSS Feed

martes, 05 de noviembre de 2019 a las 11:49hs por Gustavo Cantero (The Wolf)

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!

2 comentarios »

  1. David Ferney Cruz Cruz dice:

    Buenas tardes amigo, una consulta, veo que el datepicker cambia con respecto a la versión de android. estoy haciendo un prueba tecnica donde se evidencia que cambia el aspecto. se puede regresar a una version anterior ? ejemplo tener una version de andoid 10 y con una version de 4.4 de datepicker ? se puede hacer ?

    • Hola David.
      No, no se puede hacer eso, ya que cada Android tiene sus propios widgets. Incluso los fabricantes (Samsung, Xiaomi, etc.) también pueden cambiar algunas de esas cosas y tener diferencias entre las mismas versiones de Android de distintos marcas.
      Saludos.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.