Change the text color of NumberPicker

The solution I tried and worked for me is:

In styles.xml add:

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

Then use it like this inside your layout:

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

Not sure why you would need to dive into Java Reflection API for this. Its a simple styling matter. The attribute that you need to override is: textColorPrimary.

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

If you're using the TimePicker inside a Dialog, override android:textColorPrimary in the dialog's theme.

That's about it.

Additional info:

Here's an insightful comment by 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

This is correct, but it overlooks the possibilities I am hinting at. Moreover, global implies app-wide impact. That can be limited to activity-scope by applying this theme only to activities containing the NumberPicker. But, I agree, this may still be too corrosive.

The idea here is to somehow inject textColorPrimary=INTENDED_COLOR into the theme that will be seen by NumberPicker. There are multiple ways to achieve this. Here's one way:

Define a bare-bone style in res/values/styles.xml:

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

Now, create a custom 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);
    }
}

Finally, use ThemedNumberPicker in your layout(s):

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

We have successfully contained the impact that textColorPrimary=INTENDED_COLOR has on our app.

This is of course just one option. For example, if you were inflating a layout containing a NumberPicker, you could use:

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

This code should solve your problem. The problem you are experiencing is because during the construction of NumberPicker it captures the EditText textColor and assigns to to a paint so it can draw the numbers above and below the edit text with the same color.

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