Android: ¿cómo cambiar el color del divisor datepicker?

Tengo un marcador de fecha en mi aplicación para Android, pero ahora quiero cambiar el color de los divisores azules a verde (ver la imagen debajo de este texto). Hay algunas otras discusiones sobre Stackoverflow que hablan sobre lo mismo, pero ninguna de ellas da una respuesta que conduzca a una solución.

Así que fui a buscarme y descubrí que en realidad hay un android: datePickerStyle y también hay un android: divider. No obstante, no sé si el divisor realmente se está refiriendo al separador en el marcador de fecha. Probé una multitud de combinaciones de los dos, pero parece que no lo hago funcionar. Entonces mi primera pregunta: ¿el android: divider se refiere al divisor en el datepicker, y cómo podría usarlo para cambiar el color?

Entonces, se supone que otra opción es crear un marcador de fecha personalizado completamente nuevo. Si eso me permite simplemente cambiar el color del divisor, estoy desanimado. Así que eché un vistazo a algunos de los tutoriales sobre cómo crear un marcador de fecha personalizado, pero ninguno de ellos parece definir el color de los separadores. Los divisores simplemente no están listados en los archivos xml o en los archivos java.

Sería genial si hubiera algún tipo de código repetitivo para recrear el datepicker tal como se muestra actualmente, incluido el código que establece el color de los divisores. Espero que eso me permita copiarlo y simplemente cambiar la configuración de color del divisor en alguna parte. Entonces mi segunda pregunta: ¿Alguien sabría algún código repetitivo que simplemente implemente el datepicker tal como está ahora (incluida una definición de los divisores)?

enter image description here

Desafortunadamente, esta no es una tarea trivial.

DatePickers usa los widgets NumberPicker y CalendarView internamente. Por ejemplo, la imagen que ha publicado usa 3 NumberPickers . Y los divisores de los que está hablando provienen del atributo NumberPicker: selectionDivider . El problema es que este atributo no es público, y tampoco lo es numberPickerStyle , a través del cual se establece este atributo.

Hace poco exporté CalendarView y NumberPicker a API 8, principalmente por diversión. Debido a que el código está disponible (busque android.widget.NumberPicker y otros en la fuente de Android), toda esta tarea requiere tiempo y algo de búsqueda en el código fuente de Android. Ejemplos:

  1. Fácil ==> Tendrás que cambiar la variable privada de la clase View a sus métodos de acceso

    mLeft (variable protegida en clase de vista) ==> getLeft () (método de acceso público)

  2. La tarea que más tiempo consumió fue la restauración de los métodos de accesibilidad.

En cualquier caso, si decides escribir una implementación personalizada de DatePicker, tendrás que escribirlos también para NumberPicker y CalendarView (opcionalmente).

Manera más fácil:

Backported DatePicker está disponible como biblioteca aquí: Android-DatePicker . Como se mencionó anteriormente, usará CalendarView y NumberPicker con soporte junto con este DatePicker.

Lo que necesitas cambiar:

Utilice {library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.png como plantilla, y cambie el color ‘azulado’ a verde (utilicé pixlr ). Puede guardarlo con el mismo nombre, si desea terminar con el divisor azul, o usar un nombre diferente y realizar cambios en {library-numberpicker} / res / values / themes.xml .

Los cambios requeridos en themes.xml si elige un nombre diferente:

  

Y eso es.

Salida usando las bibliotecas:

enter image description here

Editar:

¿El android:divider refiere al divisor en el datepicker, y cómo podría usarlo para cambiar el color?

El divider atributos en realidad proviene de LinearLayout . NumberPicker hereda este atributo ya que NumberPicker extends LinearLayout . Pero este divider tiene un propósito diferente. El dibujo que se pasa a este atributo se coloca entre vistas secundarias de LinearLayout .

El atributo android:showDividers se usa para cambiar la ubicación de este divisor, siendo posibles valores:

  • ninguno: no se muestran divisores
  • begin: Divider se muestra antes de la primera vista de niño
  • medio: el divisor se muestra después de cada vista secundaria, no después de la última vista secundaria
  • end: Divider se muestra después de la última vista de niño

El atributo android:dividerPadding es autoexplicativo.

Aunque NumberPicker hereda este atributo, no lo usa. Esto es evidente a partir de sus propias investigaciones y ensayos: I tried a multitude of combinations of the two, but I don't seem to get it to work.

Para ver el atributo del divisor en acción:

      

Hack-ish solución utilizando la reflexión de Java:

Esta respuesta aquí me dio la idea. Odio el uso de la reflexión en general, principalmente por los motivos enumerados en esta respuesta: Enlace . Aunque lo estoy enumerando aquí para su integridad, le sugiero que no lo use.

 public class CDP extends android.widget.DatePicker { public CDP(Context context, AttributeSet attrs) { super(context, attrs); Class< ?> internalRID = null; try { internalRID = Class.forName("com.android.internal.R$id"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Field month = null; try { month = internalRID.getField("month"); } catch (NoSuchFieldException e) { e.printStackTrace(); } NumberPicker npMonth = null; try { npMonth = (NumberPicker) findViewById(month.getInt(null)); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } Field day = null; try { day = internalRID.getField("day"); } catch (NoSuchFieldException e) { e.printStackTrace(); } NumberPicker npDay = null; try { npDay = (NumberPicker) findViewById(day.getInt(null)); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } Field year = null; try { year = internalRID.getField("year"); } catch (NoSuchFieldException e) { e.printStackTrace(); } NumberPicker npYear = null; try { npYear = (NumberPicker) findViewById(year.getInt(null)); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } Class< ?> numberPickerClass = null; try { numberPickerClass = Class.forName("android.widget.NumberPicker"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Field selectionDivider = null; try { selectionDivider = numberPickerClass.getDeclaredField("mSelectionDivider"); } catch (NoSuchFieldException e) { e.printStackTrace(); } try { selectionDivider.setAccessible(true); selectionDivider.set(npMonth, getResources().getDrawable( R.drawable.np_numberpicker_selection_divider_green)); selectionDivider.set(npDay, getResources().getDrawable( R.drawable.np_numberpicker_selection_divider_green)); selectionDivider.set(npYear, getResources().getDrawable( R.drawable.np_numberpicker_selection_divider_green)); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } 

Qué hacemos aquí:

  • Extiende DatePicker
  • Si abre date_picker.xml en sdk/platforms/android-xx/res/layout , verá que los tres NumberPickers tienen identificadores month , day , year . android.internal.R.id a android.internal.R.id para obtener identificadores de recursos para estos NumberPickers.
  • Creamos tres objetos NumberPicker usando estos identificadores con el findViewById(int) .
  • Luego, acceda y recupere el Campo mSelectionDivider usando mSelectionDivider .
  • Establezca el campo en accesible (como su final declarado), establezca su valor usando Field#set(Object, Object) método Field#set(Object, Object) . El primer argumento es el Objeto en el que realizamos esta operación. El segundo argumento es el Objeto que queremos establecer.

El dibujable que he usado se puede descargar de: aquí .

Creo que la solución más simple es usar estilos.

Solo ponga esto en su documento de styles.xml

      

y pon estos atributos en tu diseño XML

 android:theme="@style/appCompatStyle" 

y personalízala como quieras.

Hay una biblioteca que tienen tiempo de custmize y selector de fecha. En eso puedes cambiar el color del divisor de la siguiente manera

  timePicker.setSelectionDivider(new ColorDrawable(0xffff0000)); timePicker.setSelectionDividerHeight(2); 

Editar Otra biblioteca que también he usado, que también es buena, se puede personalizar de la siguiente manera en thems.xml

  

Ante todo; ¡Vikram, hiciste un gran trabajo gracias por tu esfuerzo! Una cosa que me faltaba en net.simonvt.datepicker.DatePickerDialog era la opción para establecer el color titleDivider que quiero numberPickerDividerColor con numberPickerDividerColor . Así que agregué esta opción en la implementación de Vikram y la estoy publicando aquí. Es una solución común relacionada con el cambio de AlertDialog.titleDividerColor . Quizás ayudará a alguien.

 class net.simonvt.datepicker.DatePickerDialog private int titleDividerColor; 

Es importante establecer el color cuando se muestra el cuadro de diálogo, por lo que hago esto en el método onAttachedToWindow .

 @Override public void onAttachedToWindow() { super.onAttachedToWindow(); if (titleDividerColor < = 0) { return; } try { int dividerId = getContext().getResources().getIdentifier("android:id/titleDivider", null, null); View divider = findViewById(dividerId); if (divider != null) { divider.setBackgroundColor(getContext().getResources().getColor(titleDividerColor)); } } catch (Exception e) {} } public void setTitleDividerColor(int titleDividerColor) { this.titleDividerColor = titleDividerColor; } public int getTitleDividerColor() { return titleDividerColor; } 

EDITAR

Publiqué otra solución aquí https://stackoverflow.com/a/33800696/1134335

Para cambiar solo el color del divisor en DatePickerDialog, cambiar el estilo de android: datePickerDialogTheme en el tema es suficiente:

Estilo del tema:

   

Estilo de diálogo:

  

Establecer un tema para el diseño DatePicker y agregar colorControlNormal a él funciona para mí.

En el xml de su diseño, agregue un DatePicker aplicando un tema como se muestra a continuación:

  

y luego define NumberPickerStyle en styles.xml especificando colorControlNormal esta manera:

  

De Wrecker en Android divider color DatePicker dialog

Puede usar estos atributos por ejemplo: