Android 更改 NumberPicker 的文本颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22962075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:36:51  来源:igfitidea点击:

Change the text color of NumberPicker

androidtextcolornumberpicker

提问by Odaym

I've looked at most all of the threads on this and none provided an answer that works. Styling the NumberPicker does not work (as per this thread: NumberPicker textColour)

我已经查看了大多数关于此的线程,但没有一个提供有效的答案。样式 NumberPicker 不起作用(根据此线程:NumberPicker textColour

Setting the style attribute on the numberPicker to a style that has a color item does not have any effect either. Nor does setting the textColor attribute on the numberPicker XML do anything.

将 numberPicker 上的 style 属性设置为具有颜色项的样式也没有任何效果。在 numberPicker XML 上设置 textColor 属性也没有任何作用。

Closest I've got to this is using the numberPicker to cast its getChildAt() to an EditText and then do setColor() on that EditText, but that only changes the color of the child once upon initialization and then every time it is selected from thereon; not what I am looking for either.

我最接近的是使用 numberPicker 将其 getChildAt() 转换为 EditText,然后在该 EditText 上执行 setColor(),但这只会在初始化时更改孩子的颜色一次,然后每次从在其上;也不是我要找的。

Any help? Thanks

有什么帮助吗?谢谢

回答by Simon

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.

此代码应该可以解决您的问题。您遇到的问题是因为在 NumberPicker 的构建过程中,它会捕获 EditText textColor 并分配给油漆,以便它可以使用相同颜色绘制编辑文本上方和下方的数字。

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

回答by z3n105

The solution I tried and worked for me is:

我尝试并为我工作的解决方案是:

In styles.xml add:

在styles.xml中添加:

<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" />

回答by Vikram

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.

不知道为什么您需要为此深入研究 Java 反射 API。这是一个简单的造型问题。您需要覆盖的属性是:textColorPrimary

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

If you're using the TimePickerinside a Dialog, override android:textColorPrimaryin the dialog's theme.

如果您使用TimePicker内部 a Dialog,则覆盖android:textColorPrimary对话框的主题。

That's about it.

就是这样。

Additional info:

附加信息:

Here's an insightful comment by Yoann Hercouet:

以下是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

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

This is correct, but it overlooks the possibilities I am hinting at. Moreover, globalimplies 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.

这是正确的,但它忽略了我暗示的可能性。此外,global意味着应用程序范围的影响。通过将此主题仅应用于包含NumberPicker. 但是,我同意,这可能仍然太具有腐蚀性

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

这里的想法是某种方式注入textColorPrimary=INTENDED_COLOR到将略见一斑主题NumberPicker。有多种方法可以实现这一点。这是一种方法:

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

在 中定义一个简单的样式res/values/styles.xml

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

Now, create a custom NumberPicker:

现在,创建一个自定义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 ThemedNumberPickerin your layout(s):

最后,ThemedNumberPicker在您的布局中使用:

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

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

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

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

这当然只是一种选择。例如,如果您要膨胀包含 a 的布局NumberPicker,您可以使用:

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

回答by Andreas Merz

Here is a Xamarin Snippet from the answer above with TextSize and TextStyle Bold

这是上面答案中的 Xamarin 片段,带有 TextSize 和 TextStyle Bold

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

回答by Dinidiniz

Instead of changing every text color to the color you want, better just changing all editText color. NumberPicker actually has a child EditText that display the numbers.

与其将每个文本颜色更改为您想要的颜色,不如更改所有 editText 颜色。NumberPicker 实际上有一个显示数字的子 EditText。

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

This worked for me. And although I have white text in the buttons, they havent changed.

这对我有用。虽然我的按钮中有白色文字,但它们并没有改变。

回答by Tapa Save

Based on reflection reject on Android SDK >= 29 better to modify Simon's answer:

基于 Android SDK >= 29 上的反射拒绝更好地修改西蒙的答案:

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

In SDK >= 29 NumberPicker have .setTextColor() method.

在 SDK >= 29 NumberPicker 中有 .setTextColor() 方法。

回答by Eduardo Reis

I took the solution of @Andreas Merzand updated his code. The way things were assigned and the functions signatures/calls he used were not found. I am using min API 19. Here is the code that worked for me.

我采用了@Andreas Merz的解决方案并更新了他的代码。未找到分配事物的方式以及他使用的函数签名/调用。我正在使用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();
            }
        }
    }
}

回答by mgm

The accepted answer is overly complicated. A much simpler approach that worked for me was to override the: textColorPrimaryattribute of the theme I was using.

接受的答案过于复杂。对我有用的更简单的方法是覆盖textColorPrimary我正在使用的主题的:属性。

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

It did the job quite well!

它做得很好!

回答by Arbitur

For me setting android:textColorPrimaryin my theme did nothing, looking at the source code for the NumberPickerit decides the text color from the EditTextinput thus one need to set the android:editTextColorinstead.

对我来说,android:textColorPrimary在我的主题中设置什么也没做,查看源代码NumberPicker它决定了EditText输入中的文本颜色,因此需要设置它android:editTextColor

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:editTextColor">@color/dark_gray</item>
</style>

回答by Tamás Sajti

It's easy with my NumberPicker library.

使用我的 NumberPicker很容易。

<com.github.tomeees.scrollpicker.ScrollPicker
    ...
    app:textColor="..."
    />