Cambio del color del divisor de NumberPicker

En las versiones recientes de android, los recolectores de números usan un divisor azul cuando son dibujados (ver imagen abajo).

Introduzca aquí la descripción de la imagen

Me gustaría cambiar este color. ¿Hay una solución de trabajo? O quizás una biblioteca que empaqueta una versión actualizada de NumberPicker que permite personalizar el color del divisor?

He intentado android-numberpicker pero consigo un error (véase abajo) en tiempo de ejecución debido a cierto código de la biblioteca que intenta tener acceso a una identificación del recurso que no existe.

android.content.res.Resources$NotFoundException: Resource ID #0x0 at android.content.res.Resources.getValue(Resources.java:1123) at android.content.res.Resources.loadXmlResourceParser(Resources.java:2309) at android.content.res.Resources.getLayout(Resources.java:939) at android.view.LayoutInflater.inflate(LayoutInflater.java:395) at net.simonvt.numberpicker.NumberPicker.<init>(NumberPicker.java:635) at net.simonvt.numberpicker.NumberPicker.<init>(NumberPicker.java:560) at net.simonvt.numberpicker.NumberPicker.<init>(NumberPicker.java:550) 

Basado en esto ( https://stackoverflow.com/a/20291416/2915480 aunque es sobre DatePicker) hay varias maneras:

  1. Escriba su propio NumberPicker sin mSelectionDivider y sus afiliados o use backported por Vikram . En el último caso:

    1. Descargar desde lib de github
    2. Cambio drawable en res / drawable-xxx / np_numberpicker_selection_divider.9.png:

      • A transparente (o lo que sea).
      • Crear np_numberpicker_selection_divider.xml forma línea recurso en res / 0dp (con 0dp altura o color transparente).
    3. OR remove if (mSelectionDivider != null) rama del método onDraw (Canvas) en NumberPicker.java como aquí

  2. Utilice la reflexión para acceder private final field mSelectionDivider (detalles: https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/NumberPicker.java ) – por ejemplo vea la modificación aquí . He utilizado la reflexión, pero no es la mejor solución.

Si desea simplemente cambiar el color (basado en la respuesta de estannos):

 private void setDividerColor(NumberPicker picker, int color) { java.lang.reflect.Field[] pickerFields = NumberPicker.class.getDeclaredFields(); for (java.lang.reflect.Field pf : pickerFields) { if (pf.getName().equals("mSelectionDivider")) { pf.setAccessible(true); try { ColorDrawable colorDrawable = new ColorDrawable(color); pf.set(picker, colorDrawable); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (Resources.NotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } } 

Y después de eso

 setDividerColor(mNumberPicker, Color.GREEN); 

Soy método de solución de uso

  private void setDividerColor (NumberPicker picker) { java.lang.reflect.Field[] pickerFields = NumberPicker.class.getDeclaredFields(); for (java.lang.reflect.Field pf : pickerFields) { if (pf.getName().equals("mSelectionDivider")) { pf.setAccessible(true); try { //pf.set(picker, getResources().getColor(R.color.my_orange)); //Log.v(TAG,"here"); pf.set(picker, getResources().getDrawable(R.drawable.dot_orange)); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } //} } 

Y aplique su

  setDividerColor(yourNumberPicker); 

Soy bastante nuevo en Android, así que tenga en cuenta que esta solución puede no ser una buena práctica, pero encontré una forma (hacky) de obtener este efecto utilizando sólo XML / WITHOUT reflexión.

Pude "cambiar" los colores de los divisores en mis NumberPickers dentro de LinearLayout agregando 2 vistas delgadas y horizontales al ViewGroup, dándoles márgenes de disposición negativos y el color deseado para sus fondos:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_gravity="center_horizontal" android:gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" > <NumberPicker android:layout_width="70dip" android:layout_height="wrap_content" android:focusable="true" android:focusableInTouchMode="true" android:layout_gravity="center" android:layout_margin="5dp" /> <View android:layout_height="2dp" android:layout_width="70dp" android:background="@color/myColor" android:layout_gravity="center_vertical" android:layout_marginLeft="-75dp" android:layout_marginBottom="-25dp"> </View> <View android:layout_height="2dp" android:layout_width="70dp" android:background="@color/myColor" android:layout_gravity="center_vertical" android:layout_marginLeft="-70dp" android:layout_marginBottom="25dp"> </View> </LinearLayout> 

Es cierto que no estoy cambiando el color, pero añadiendo nuevas líneas con el color deseado encima de los divisores incorporados. Espero que esto ayude a alguien de todos modos!

Puede que tenga que jugar con los márgenes, pero estos ajustes fueron perfectos para mi diálogo personalizado.

Esto funcionó para mí sin usar la reflexión.

My_layout.xml

 <NumberPicker ... android:theme="@style/DefaultNumberPickerTheme" /> 

Styles.xml (AppTheme es el tema de mi aplicación en la aplicación)

 <style name="DefaultNumberPickerTheme" parent="AppTheme"> <item name="colorControlNormal">@color/dividerColor</item> </style> 

Utilizo el código abajo para cambiar el divisor, no directamente el color, pero usted puede hacer eso con un png como esto .

Esta solución que te traigo viene de aquí , pero mi código es una simplificación fácil para cambiar el divisor y eso es todo.

  // change divider java.lang.reflect.Field[] pickerFields = NumberPicker.class .getDeclaredFields(); for (java.lang.reflect.Field pf : pickerFields) { if (pf.getName().equals("mSelectionDivider")) { pf.setAccessible(true); try { pf.set(spindle, getResources().getDrawable(R.drawable.np_numberpicker_selection_divider_green)); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } 

Puede utilizar la reflexión para hacer el truco. Aquí está mi solución

 public class ColorChangableNumberPicker extends NumberPicker { public ColorChangableNumberPicker(Context context) { super(context); init(); } public ColorChangableNumberPicker(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ColorChangableNumberPicker(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public ColorChangableNumberPicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); } private void init() { setDividerColor(Color.RED); } public void setDividerColor(@ColorInt int color) { try { Field fDividerDrawable = NumberPicker.class.getDeclaredField("mSelectionDivider"); fDividerDrawable.setAccessible(true); Drawable d = (Drawable) fDividerDrawable.get(this); d.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); d.invalidateSelf(); postInvalidate(); // Drawable is dirty } catch (Exception e) { } } } 

Usando este código para evry cosa que quieres hacer con divider

 Field[] pickerFields = NumberPicker.class.getDeclaredFields(); for (Field pf : pickerFields) { if (pf.getName().equals("mSelectionDivider")) { pf.setAccessible(true); try { pf.set(picker, getResources().getDrawable(R.drawable.divider)); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } 

Es mejor guardar un campo privado si va a cambiar el color del divisor en el futuro. Me gusta esto:

 @Nullable private Field dividerField; public void setDivider(@Nullable Drawable divider) { try { if (dividerField == null) { dividerField = NumberPicker.class.getDeclaredField("mSelectionDivider"); dividerField.setAccessible(true); } dividerField.set(this, divider); } catch (Exception ignore) {} } 

La forma más sencilla es agregar este atributo en su selector NumberPicker en xml

 android:selectionDivider="@colors/your_color" 
  • ¿Cómo implementar android Minutos-Segundos selector?
  • AlertDialog con NumberPicker procesado incorrectamente
  • Cambiar el color de texto de NumberPicker
  • Android Loading Selector de números personalizado Drawable
  • ¿Cómo obtener el número seleccionado de NumberPicker?
  • Android numberpicker para números de coma flotante
  • ¿Cómo saltar un número de selector de números?
  • El valor predeterminado de Android Numberpicker no viene
  • Implementar OnValueChange a un NumberPicker en Android
  • ¿Cómo se muestra un NumberPicker de 2 dígitos en android?
  • NPE en ChangeCurrentByOneFromLongPressCommand (en dispositivos Samsung con Android 4.3)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.