number library ejemplo android android-styles numberpicker

library - picker dialog android



Cambio del color del divisor NumberPicker (11)

En las versiones recientes de Android, los recolectores de números usan un divisor azul cuando se dibujan (ver imagen abajo).

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

He probado android-numberpicker pero recibo un error (ver más abajo) en el tiempo de ejecución debido a algún código de la biblioteca que intenta acceder a un ID de 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://.com/a/20291416/2915480 aunque se trata de DatePicker) hay varias maneras:

  1. Escriba su propio NumberPicker sin mSelectionDivider y sus afiliados o use el backport de https://.com/a/20291416/2915480 . En el último caso:

    1. descargar desde lib desde github
    2. cambiar dibujable en res / drawable-xxx / np_numberpicker_selection_divider.9.png:

      • a transparente (o lo que sea) .9.png
      • cree np_numberpicker_selection_divider.xml recurso de línea de forma en res / 0dp (con altura 0dp o color transparente).
    3. O elimine if (mSelectionDivider != null) ramifica desde el método onDraw (Canvas) en NumberPicker.java como here

  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 here . Usé la reflexión pero no es la mejor solución.


Es fácil con mi biblioteca (también hice mi propio NumberPicker).

android:selectionDivider="@colors/your_color"


Es mejor almacenar 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) {} }


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>


Estoy usando el método de solución

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 aplicar su

setDividerColor(yourNumberPicker);


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

android:selectionDivider="@colors/your_color"


Puedes usar 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) { } } }


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

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 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 solo XML / WITHOUT reflejo.

Pude "cambiar" los colores de los divisores en mis NumberPickers dentro de un LinearLayout agregando 2 vistas delgadas y horizontales al ViewGroup, y dándoles márgenes de diseño negativos y mi 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 realmente el color, sino que estoy agregando nuevas líneas con mi color deseado en la parte superior de los divisores incorporados. Esperemos que esto ayude a alguien de todos modos!

Puede que tenga que jugar con los márgenes, pero esta configuración fue perfecta para mi diálogo personalizado.


Uso el siguiente código para cambiar el divisor, no directamente el color, pero puedes hacerlo con un png como este .

Esta solución que les traigo viene de here , 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; } }


usando este código para lo que quieras hacer con el divisor

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; } }