Sur les versions récentes d'Android, les sélecteurs nombre utilisent un séparateur bleu lors du tirage (cf. image ci-dessous).
Je voudrais changer cette couleur. Y a-t-il une solution de travail? ou peut-être une bibliothèque qui contient une version mise à jour de NumberPicker qui permet de personnaliser la couleur du séparateur?
J'ai essayé Android-numberpicker mais je reçois une erreur (voir ci-dessous) à l'exécution à cause d'un code de la bibliothèque qui tente d'accéder à un identifiant de ressource inexistant.
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)
Basé sur ceci ( https://stackoverflow.com/a/20291416/2915480 bien qu'il s'agisse de DatePicker), il y a plusieurs façons:
Écrivez votre propre NumberPicker sans mSelectionDivider et ses filiales, ni utilisez le port backporté par Vikram . Dans le dernier cas:
change dessable dans res/drawable-xxx/np_numberpicker_selection_divider.9.png:
0dp
hauteur ou couleur transparente).OU supprimez la branche if (mSelectionDivider != null)
de la méthode onDraw (Canvas) dans NumberPicker.Java like here
Utilisez la réflexion pour accéder à private final field mSelectionDivider
(détails: https://github.com/Android/platform_frameworks_base/blob/master/core/Java/Android/widget/NumberPicker.Java ) - p. Ex. voir modification ici . J'ai utilisé la réflexion mais ce n'est pas la meilleure solution.
Si vous voulez simplement changer la couleur (en fonction de la réponse 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;
}
}
}
Et après ça
setDividerColor(mNumberPicker, Color.GREEN);
Cela a fonctionné pour moi sans utiliser le reflet.
my_layout.xml
<NumberPicker
...
Android:theme="@style/DefaultNumberPickerTheme" />
Styles.xml (AppTheme est le thème de mon application dans l'application)
<style name="DefaultNumberPickerTheme" parent="AppTheme">
<item name="colorControlNormal">@color/dividerColor</item>
</style>
J'utilise la méthode de contournement Java:
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;
}
}
//}
}
ou méthode Kotlin:
private fun NumberPicker.setDividerColor(color: Int) {
val dividerField = NumberPicker::class.Java.declaredFields.firstOrNull { it.name == "mSelectionDivider" } ?: return
try {
dividerField.isAccessible = true
dividerField.set(this,getResources().getDrawable(R.drawable.dot_orange))
} catch (e: Exception) {
e.printStackTrace()
}
}
Et appliquer ses
setDividerColor(yourNumberPicker); // for Java method
yourNumberPicker.setDividerColor(Color.RED) // for kotlin method
Comme je suis assez nouveau sur Android, n'oubliez pas que cette solution n'est peut-être pas une bonne pratique, mais j'ai trouvé un moyen (hacky) d'obtenir cet effet en utilisant uniquement XML/SANS réflexion.
J'ai été en mesure de "changer" les couleurs des séparateurs de mes NumberPickers dans LinearLayout en ajoutant 2 minces vues horizontales au ViewGroup et en leur donnant des marges de mise en page négatives ainsi que la couleur souhaitée pour leurs arrière-plans:
<?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>
Certes, je ne change pas la couleur, mais j'ajoute de nouvelles lignes avec la couleur souhaitée au-dessus des séparateurs intégrés. Espérons que cela aide quelqu'un quand même!
Vous devrez peut-être jouer avec les marges, mais ces paramètres étaient parfaits pour ma boîte de dialogue personnalisée.
Vous pouvez utiliser la réflexion pour faire l'affaire. Voici ma solution
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) {
}
}
}
J'utilise le code ci-dessous pour changer le séparateur, pas directement la couleur, mais vous pouvez le faire avec un png comme ceci .
Cette solution que je vous apporte vient de ici , mais mon code est une simplification facile pour changer le diviseur et c'est tout.
// 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;
}
}
C'est facile avec ma bibliothèque (j'ai aussi lancé mon propre NumberPicker).
<com.github.tomeees.scrollpicker.ScrollPicker
...
app:selectorColor="..."
/>
Il est préférable de stocker un champ privé si vous souhaitez modifier la couleur du séparateur à l'avenir. Comme ça:
@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) {}
}
en utilisant ce code pour tout ce que vous voulez faire avec diviseur
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;
}
}