更改NumberPicker的文本颜色

我已经查看了大多数所有的线程,没有提供一个有效的答案。 样式NumberPicker不起作用(按照此线程: NumberPicker textColour )

将numberPicker上的style属性设置为具有颜色项目的样式也没有任何效果。 在numberPicker XML上设置textColor属性也不做任何事情。

最近我得到这个是使用numberPicker将其getChildAt()强制转换为EditText,然后在该EditText上执行setColor(),但只是在初始化时更改子对象的颜色,然后每次从在其上; 不是我正在寻找的。

任何帮助? 谢谢

这段代码应该能解决你的问题。 您遇到的问题是因为在NumberPicker的构build过程中,它捕获EditText textColor并将其分配给一个绘画,以便它可以使用相同的颜色绘制编辑文本上方和下方的数字。

import java.lang.reflect.Field; public static boolean setNumberPickerTextColor(NumberPicker numberPicker, int color) { final int count = numberPicker.getChildCount(); for(int i = 0; i < count; i++){ View child = numberPicker.getChildAt(i); if(child instanceof EditText){ try{ Field selectorWheelPaintField = numberPicker.getClass() .getDeclaredField("mSelectorWheelPaint"); selectorWheelPaintField.setAccessible(true); ((Paint)selectorWheelPaintField.get(numberPicker)).setColor(color); ((EditText)child).setTextColor(color); numberPicker.invalidate(); return true; } catch(NoSuchFieldException e){ Log.w("setNumberPickerTextColor", e); } catch(IllegalAccessException e){ Log.w("setNumberPickerTextColor", e); } catch(IllegalArgumentException e){ Log.w("setNumberPickerTextColor", e); } } } return false; } 

我尝试过的解决scheme是:

在styles.xml中添加:

 <style name="AppTheme.Picker" parent="Theme.AppCompat.Light.NoActionBar" > <item name="android:textColorPrimary">@android:color/black</item> </style> 

然后像这样在你的布局中使用它:

  <NumberPicker android:id="@+id/dialogPicker" android:theme="@style/AppTheme.Picker" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="15dp" /> 

不知道为什么你需要为此进行JavareflectionAPI。 它是一个简单的造型问题。 您需要覆盖的属性是: textColorPrimary

 <style name="AppTheme" parent="@android:style/Theme.Holo.Light"> .... <item name="android:textColorPrimary">#ff0000</item> </style> 

如果您在Dialog使用TimePicker ,请覆盖对话框主题中的android:textColorPrimary

就是这样。

附加信息:

以下是Yoann Hercouet的深刻见解:

此解决scheme不会仅更改NumberPicker上的颜色,而是会影响很多组件的全局更改

这是正确的,但忽略了我暗示的可能性。 而且, global意味着应用程序范围的影响。 通过将此主题仅应用于包含NumberPicker活动,可将其限制为活动范围。 但是,我同意,这可能仍然是腐蚀性的

这里的想法是以某种方式将textColorPrimary=INTENDED_COLOR插入到NumberPicker将看到的主题中。 有多种方法来实现这一点。 这里有一个方法:

res/values/styles.xml定义一个裸骨样式:

 <style name="NumberPickerTextColorStyle"> <item name="android:textColorPrimary">@color/intended_color</item> </style> 

现在,创build一个自定义的NumberPicker

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

最后,在布局中使用ThemedNumberPicker

 <package.name.ThemedNumberPicker android:id="@+id/numberPicker" .... .... .... /> 

我们已经成功地包含了textColorPrimary=INTENDED_COLOR对我们的应用程序的影响。

这当然只是一个select。 例如,如果您正在为包含NumberPicker的布局充气,则可以使用:

 // In this case, the layout contains <NumberPicker... />, not <ThemedNumberPicker... /> LayoutInflater.from(new ContextThemeWrapper(context, R.style.NumberPickerTextColorStyle)) .inflate(R.layout.number_picker_layout, ...); 

这里是从上面的答案的TextSize和TextStyle粗体Xamarin片段

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

被接受的答案过于复杂。 为我工作的一个更简单的方法是重写我使用的主题: textColorPrimary属性。

 <style name="Theme.MyTheme" parent="@android:style/Theme.Holo.NoActionBar.Fullscreen" > <item name="android:textColorPrimary">#000000</item> </style> 

它做得很好!

而不是将每个文本颜色更改为所需颜色,最好只更改所有editText颜色。 NumberPicker实际上有一个显示数字的子EditText。

 <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.NoActionBar"> <!-- Change edit color here. --> <item name="android:editTextColor">#000000</item> </style> 

这对我有效。 虽然我在button中有白色的文字,他们没有改变。

我采取了@Andreas Merz的解决scheme,并更新了他的代码。 事情被分配的方式和他使用的function签名/调用没有被发现。 我正在使用min API 19 。 这是为我工作的代码。

 /** * 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(); } } } }