Изменение цвета разделителя NumberPicker
В последних версиях Android, подборщики чисел используют синий разделитель при рисовании (см. изображение ниже).
![enter image description here]()
Я хотел бы изменить этот цвет. Есть ли рабочее решение? или, возможно, библиотеку, в которой установлена обновленная версия NumberPicker, которая позволяет настроить цвет разделителя?
Я пробовал android-numberpicker, но я получил ошибку (см. ниже) во время выполнения из-за некоторого кода из библиотеки, которая пытается получить доступ к идентификатору ресурса, который не существует.
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)
Ответы
Ответ 1
Исходя из этого (fooobar.com/questions/165510/..., хотя это касается DatePicker) существует несколько способов:
-
Напишите свой собственный номерной номер без mSelectionDivider и его веток или используйте backported Vikram. В последнем случае:
- скачать из lib из github
-
изменить drawable в res/drawable-xxx/np_numberpicker_selection_divider.9.png:
- для прозрачного (или любого другого).9.png
- создайте ресурс строки формы np_numberpicker_selection_divider.xml в res/drawable (с ростом
0dp
или прозрачным цветом).
-
ИЛИ удалите ветвь if (mSelectionDivider != null)
из метода onDraw (Canvas) в NumberPicker.java, например здесь
-
Используйте отражение для доступа private final field mSelectionDivider
(подробности: https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/NumberPicker.java) - например. см. модификацию здесь.
Я использовал отражение, но это не лучшее решение.
Ответ 2
Если вы хотите просто изменить цвет (на основе ответа на 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;
}
}
}
И после этого
setDividerColor(mNumberPicker, Color.GREEN);
Ответ 3
Это работало для меня без использования отражения.
my_layout.xml
<NumberPicker
...
android:theme="@style/DefaultNumberPickerTheme" />
Styles.xml(AppTheme - это тема моего приложения в приложении)
<style name="DefaultNumberPickerTheme" parent="AppTheme">
<item name="colorControlNormal">@color/dividerColor</item>
</style>
Ответ 4
Я использую обходной метод 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;
}
}
//}
}
или метод Котлина:
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()
}
}
И применить его
setDividerColor(yourNumberPicker); // for java method
yourNumberPicker.setDividerColor(Color.RED) // for kotlin method
Ответ 5
Я новичок в Android, поэтому имейте в виду, что это решение может быть не очень хорошей практикой, но я нашел (хакерский) способ получить этот эффект, используя только отражение XML/WITHOUT.
Я смог "изменить" цвета разделителей на моем NumberPickers в LinearLayout, добавив 2 тонких горизонтальных представления в ViewGroup и предоставив им отрицательные макеты и желаемый цвет для их фона:
<?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>
По общему признанию, я фактически не меняю цвет, но добавляю новые строки с моим желаемым цветом поверх встроенных разделителей. Надеюсь, это кому-то поможет!
Возможно, вам придется играть с полями, но эти настройки были идеальны для моего настраиваемого диалога.
Ответ 6
Вы можете использовать отражение, чтобы сделать трюк. Вот мое решение
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) {
}
}
}
Ответ 7
Я использую приведенный ниже код, чтобы изменить разделитель, а не непосредственно цвет, но вы можете сделать это с помощью png как это.
Это решение, которое я вам приношу, происходит от здесь, но мой код - это простое упрощение для изменения разделителя и его.
// 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;
}
}
Ответ 8
используя этот код для evry, и вы хотите сделать с делителем
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;
}
}
Ответ 9
Лучше хранить частное поле, если вы собираетесь менять цвет разделителя в будущем. Вот так:
@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) {}
}
Ответ 10
Это легко с моей библиотекой (я тоже свернул свой NumberPicker).
<com.github.tomeees.scrollpicker.ScrollPicker
...
app:selectorColor="..."
/>
Ответ 11
Простейший способ - добавить этот атрибут в селектор NumberPicker в xml
android:selectionDivider="@colors/your_color"