在最近的Android版本中,number pickers在绘制时使用蓝色分隔符(参见下图)。
我想改变这种颜色。有工作的解决方案吗?或者是一个包含更新版本的NumberPicker的库,它允许自定义分隔符颜色?
我尝试过android-numberpicker,但是由于库中的一些代码试图访问不存在的资源ID,我在运行时遇到错误(见下文)。
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)
基于此(https://stackoverflow.com/a/20291416/2915480虽然它是关于DatePicker)有几种方法:
0dp
高度或透明颜色)。
或者从if (mSelectionDivider != null)
中的onDraw(Canvas)方法中移除NumberPicker.java分支,如hereprivate final field mSelectionDivider
(详情:https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/NumberPicker.java) - 例如见修改here。我使用反射,但它不是最好的解决方案。我的library很容易(我也推出了自己的NumberPicker)。
<com.github.tomeees.scrollpicker.ScrollPicker
...
app:selectorColor="..."
/>
最简单的方法是在xml中的NumberPicker选择器中添加此属性
android:selectionDivider="@colors/your_color"
如果您只想更改颜色(基于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);
这对我有用而不使用反射。
my_layout.xml
<NumberPicker
...
android:theme="@style/DefaultNumberPickerTheme" />
Styles.xml(AppTheme是应用程序中的应用主题)
<style name="DefaultNumberPickerTheme" parent="AppTheme">
<item name="colorControlNormal">@color/dividerColor</item>
</style>
我使用解决方法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;
}
}
//}
}
或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()
}
}
并应用它
setDividerColor(yourNumberPicker); // for java method
yourNumberPicker.setDividerColor(Color.RED) // for kotlin method
我对Android很新,所以请记住,这个解决方案可能不是一个好习惯,但我发现(hacky)方法只使用XML / WITHOUT反射来获得这种效果。
通过向ViewGroup添加2个细的水平视图,并为它们的背景提供负的布局边距和我想要的颜色,我能够在LinearLayout中“更改”我的NumberPickers上的分隔符的颜色:
<?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>
不可否认,我实际上并没有改变颜色,而是在内置分隔器的顶部添加了所需颜色的新线条。希望无论如何这对某人有帮助!
您可能必须使用边距,但这些设置非常适合我的自定义对话框。
你可以用反射来做这个伎俩。这是我的解决方案
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) {
}
}
}
我使用下面的代码来改变分隔符,而不是直接改变颜色,但是你可以用png like this来改变它。
我带给你的这个解决方案来自here,但我的代码是一个简单的简化来改变分频器,就是这样。
// 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;
}
}
将此代码用于你想要用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;
}
}
如果您将来要更改分隔线颜色,最好存储私有字段。像这样:
@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) {}
}