Change the text color of NumberPicker
我已经看过大多数关于此的线程,但没有一个提供有效的答案。 设置NumberPicker的样式无效(按照此线程:NumberPicker textColour)
将numberPicker上的style属性设置为具有颜色项的样式也不起作用。 在numberPicker XML上设置textColor属性也不会做任何事情。
我最接近的是使用numberPicker将其getChildAt()转换为EditText,然后对该EditText进行setColor(),但这只会在初始化后更改子项的颜色,然后每次从子项中选择子项的颜色。 在其上 不是我要找的东西。
有什么帮助吗? 谢谢
我尝试为我工作的解决方案是:
在styles.xml中添加:
1 2 3 | <style name="AppTheme.Picker" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:textColorPrimary">@android:color/black</item> </style> |
然后在您的布局中像这样使用它:
1 2 3 4 5 6 | <NumberPicker android:id="@+id/dialogPicker" android:theme="@style/AppTheme.Picker" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="15dp" /> |
这段代码应该可以解决您的问题。您遇到的问题是因为在构造NumberPicker的过程中,它将捕获EditText textColor并将其分配给绘画,以便它可以使用相同的颜色在编辑文本的上方和下方绘制数字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import java.lang.reflect.Field; public static void setNumberPickerTextColor(NumberPicker numberPicker, int color) { try{ Field selectorWheelPaintField = numberPicker.getClass() .getDeclaredField("mSelectorWheelPaint"); selectorWheelPaintField.setAccessible(true); ((Paint)selectorWheelPaintField.get(numberPicker)).setColor(color); } catch(NoSuchFieldException e){ Log.w("setNumberPickerTextColor", e); } catch(IllegalAccessException e){ Log.w("setNumberPickerTextColor", e); } catch(IllegalArgumentException e){ Log.w("setNumberPickerTextColor", e); } final int count = numberPicker.getChildCount(); for(int i = 0; i < count; i++){ View child = numberPicker.getChildAt(i); if(child instanceof EditText) ((EditText)child).setTextColor(color); } numberPicker.invalidate(); } |
不知道为什么您需要为此使用Java Reflection API。这是一个简单的样式问题。您需要覆盖的属性是:
1 2 3 4 | <style name="AppTheme" parent="@android:style/Theme.Holo.Light"> .... <item name="android:textColorPrimary">#ff0000</item> </style> |
如果在
就是这样
附加信息:
这是Yoann Hercouet的深刻见解:
This solution does not change only the color on the NumberPicker, it
is a global change that will impact A LOT of components
这是正确的,但它忽略了我所暗示的可能性。此外,
这里的想法是将
在
1 2 3 | <style name="NumberPickerTextColorStyle"> <item name="android:textColorPrimary">@color/intended_color</item> </style> |
现在,创建一个自定义
1 2 3 4 5 6 7 8 9 10 11 | public class ThemedNumberPicker extends NumberPicker { public ThemedNumberPicker(Context context) { this(context, null); } public ThemedNumberPicker(Context context, AttributeSet attrs) { // wrap the current context in the style we defined before super(new ContextThemeWrapper(context, R.style.NumberPickerTextColorStyle), attrs); } } |
最后,在您的布局中使用
1 2 3 4 5 | <package.name.ThemedNumberPicker android:id="@+id/numberPicker" .... .... .... /> |
我们已经成功地包含了
当然,这只是一种选择。例如,如果要夸大包含
1 2 3 | // In this case, the layout contains <NumberPicker... />, not <ThemedNumberPicker... /> LayoutInflater.from(new ContextThemeWrapper(context, R.style.NumberPickerTextColorStyle)) .inflate(R.layout.number_picker_layout, ...); |
这是上面答案中的Xamarin代码片段,具有TextSize和TextStyle Bold
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | public static bool SetNumberPickerTextColorAndSize(NumberPicker numberPicker, Color color, ComplexUnitType complexUnitType, float textSize, TypefaceStyle style) { int count = numberPicker.ChildCount; for (int i = 0; i < count; i++) { View child = numberPicker.GetChildAt(i); if (child.GetType() == typeof(EditText)) { try { Field selectorWheelPaintField = numberPicker.Class .GetDeclaredField("mSelectorWheelPaint"); selectorWheelPaintField.Accessible = true; EditText editText = (EditText) child; editText.SetTextSize(complexUnitType, textSize); editText.SetTypeface(editText.Typeface, style); editText.SetTextColor(color); Paint paint = (Paint) selectorWheelPaintField.Get(numberPicker); paint.TextSize = TypedValue.ApplyDimension(complexUnitType, textSize, numberPicker.Resources.DisplayMetrics); paint.Color = color; paint.SetTypeface(editText.Typeface); numberPicker.Invalidate(); return true; } catch (NoSuchFieldException e) { Log.Warn("setNumberPickerTextColor", e); } catch (IllegalAccessException e) { Log.Warn("setNumberPickerTextColor", e); } catch (IllegalArgumentException e) { Log.Warn("setNumberPickerTextColor", e); } } } return false; } |
不必将每种文本颜色更改为所需的颜色,最好只更改所有editText颜色。 NumberPicker实际上有一个显示数字的子EditText。
1 2 3 4 5 | <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.NoActionBar"> <!-- Change edit color here. --> <item name="android:editTextColor">#000000</item> </style> |
这对我有用。尽管我的按钮中有白色文字,但它们没有改变。
对我而言,在主题中设置
1 2 3 | <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:editTextColor">@color/dark_gray</item> </style> |
基于Android SDK> = 29上的反射拒绝,最好修改Simon的答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | public void setNumberPickerTextColor(NumberPicker numberPicker, int color){ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { final int count = numberPicker.getChildCount(); for (int i = 0; i < count; i++) { View child = numberPicker.getChildAt(i); if (child instanceof EditText) { try { ((EditText) child).setTextColor(color); numberPicker.invalidate(); Field selectorWheelPaintField = numberPicker.getClass().getDeclaredField("mSelectorWheelPaint"); boolean accessible = selectorWheelPaintField.isAccessible(); selectorWheelPaintField.setAccessible(true); ((Paint) selectorWheelPaintField.get(numberPicker)).setColor(color); selectorWheelPaintField.setAccessible(accessible); numberPicker.invalidate(); Field selectionDividerField = numberPicker.getClass().getDeclaredField("mSelectionDivider"); accessible = selectionDividerField.isAccessible(); selectionDividerField.setAccessible(true); selectionDividerField.set(numberPicker, null); selectionDividerField.setAccessible(accessible); numberPicker.invalidate(); } catch (Exception exception) { Logger.exc(exception); } } } } else { numberPicker.setTextColor(color); } } |
在SDK> = 29中,NumberPicker具有.setTextColor()方法。
我采用@Andreas Merz的解决方案并更新了他的代码。事物分配的方式以及他使用的功能签名/调用均未找到。我正在使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /** * Based on https://stackoverflow.com/a/26657169/2313889 * @param picker * @param color * @param unit * @param textSize * @param typeface * @return */ private void formatNumberPickerText(NumberPicker picker, int color, int unit, float textSize, Typeface typeface) { int count = picker.getChildCount(); for (int i = 0; i < count; i++) { View child = picker.getChildAt(i); if (child instanceof EditText) { try { Class clazz = picker.getClass(); Field field = clazz.getDeclaredField("mSelectorWheelPaint"); field.setAccessible(true); EditText editText = (EditText) child; editText.setTextSize(unit, textSize); editText.setTypeface(typeface); editText.setTextColor(color); Paint paint = (Paint) field.get(picker); paint.setTextSize(TypedValue.applyDimension( unit, textSize, getResources().getDisplayMetrics() )); paint.setColor(color); paint.setTypeface(typeface); picker.invalidate(); return; } catch (IllegalAccessException | NoSuchFieldException e) { e.printStackTrace(); } } } } |
公认的答案过于复杂。对我有用的一种简单得多的方法是覆盖我正在使用的主题的
1 2 3 | <style name="Theme.MyTheme" parent="@android:style/Theme.Holo.NoActionBar.Fullscreen"> <item name="android:textColorPrimary">#000000</item> </style> |
它做得很好!
使用我的NumberPicker库很容易。
1 2 3 4 | <com.github.tomeees.scrollpicker.ScrollPicker ... app:textColor="..." /> |