【问题标题】:Change the text color of NumberPicker更改 NumberPicker 的文本颜色
【发布时间】:2014-05-22 15:03:10
【问题描述】:

我查看了几乎所有关于此的主题,但没有一个提供有效的答案。 NumberPicker 的样式设置不起作用(根据此线程:NumberPicker textColour

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

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

有什么帮助吗?谢谢

【问题讨论】:

  • 我来自黎巴嫩

标签: android textcolor numberpicker


【解决方案1】:

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

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

【讨论】:

  • 这是总体上最简单和最好的答案。 +1
  • 绝对是最简单的解决方案!这也很容易与我的自定义 numberpicker 结合使用,它使用主题 @android:style/Theme.Dialog 来显示 + 和 - 按钮而不是滑块效果。现在我简单地将父主题定义为我以前的主题(而不是 Theme.AppCompat.Light.NoActionBar),它神奇地结合在一起。
  • 这是最好的答案。我希望我能投票超过 +1。
  • @z3n105 你知道改变选择颜色的属性吗?
  • 这个答案改变了数字选择器所有字段的颜色,我的意思是未选择字段的颜色也会改变。但是如果我想更改刚刚选择的字段呢?!
【解决方案2】:

此代码应该可以解决您的问题。您遇到的问题是因为在 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();  
}

【讨论】:

  • 这成功了!即使使用 net.simonvt.numberpicker !让我抓狂的是,无论我指定什么样式,我总是以黑色文本结束! (黑色背景上的黑色文字 = 无用)
  • 为我工作。你救了我从我的公寓跳下去。
  • 您需要做的就是在您的主题中覆盖textColorPrimary。在这种情况下,不需要调用反射 API。
  • 同意。但是必须说,这也会改变整个应用程序中的文本颜色,而不仅仅是可能不适合的日期时间选择器。这个问题是针对 NumberPicker 的。
  • 我不喜欢投反对票,这个答案显示了很好的努力,并且有效,但它比下面@Vikram 的答案差得多,我投反对票,因为我认为社区会更好由维克拉姆的回答提供服务。
【解决方案3】:

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

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

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

就是这样。

其他信息:

这是Yoann Hercouet 的有见地的评论:

这个解决方案不仅仅改变 NumberPicker 上的颜色,它 是一个全球性的变化,会影响很多组件

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

这里的想法是以某种方式将textColorPrimary=INTENDED_COLOR 注入NumberPicker 将看到的主题中。有多种方法可以实现这一目标。这是一种方法:

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

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

现在,创建一个自定义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 对我们应用的影响。

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

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

【讨论】:

  • 更好的方法。
  • @Milad 如果您可以提供/发布有关您的应用设置的更多详细信息,我可能会为您提供帮助。
  • 对我也不起作用。但是使用这种方法有效:stackoverflow.com/questions/13882707/…
  • @HenriquedeSousa 就像我对用户 Milad 说的那样 - 如果您可以发布您的样式设置,我可能会帮助您。此外,您链接的答案没有意义(不幸的是)。请参阅我对该答案的评论。
  • @YoannHercouet 感谢您指出这一点。让我意识到我的答案可能不像我想象的那么清楚。请检查我所做的edit
【解决方案4】:

这是来自上述答案的 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;
    }

【讨论】:

  • ComplexUnitType 类未找到
  • 你怎么称呼这个?来自自定义渲染器?
  • NumberPicker的代码中找不到addView
  • 非常感谢!一直在寻找这个。如果有人在使用 Xamarin.Android,请将此 sn-p 放在 MainActivity 或 Fragment 中。您使用 FindViewById 获取您的数字选择器,并将其传递给方法。
【解决方案5】:

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

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

【讨论】:

  • 我相信Dinidiniz 已经指出了这一点。
【解决方案6】:

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

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

这对我有用。尽管我在按钮中有白色文本,但它们并没有改变。

【讨论】:

  • 您好,我只想更改选定的编辑文本颜色,您的代码可以这样做吗?
【解决方案7】:

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

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

【讨论】:

  • 警告对 mSelectionDivider 的反射访问,它不是公共 SDK 的一部分,因此在未来的 Android 版本中可能会发生变化
【解决方案8】:

我采用了@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();
            }
        }
    }
}

【讨论】:

  • 注意:Andreas 代码适用于 Xamarin Android。这个答案适用于“普通”Android代码(Java),就像原来的问题一样。与接受的答案相比,它增加了字体和字体大小的设置。
【解决方案9】:

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

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

它做得很好!

【讨论】:

    【解决方案10】:

    Kotlin用户,使用此扩展功能(基于@Tapa Save答案)。

    fun NumberPicker.changeTextColor(color: Int) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            val count: Int = childCount
            for (i in 0 until count) {
                val child: View = getChildAt(i)
                if (child is EditText) {
                    try {
                        child.setTextColor(color)
                        invalidate()
                        val selectorWheelPaintField: Field = this.javaClass.getDeclaredField("mSelectorWheelPaint")
                        var accessible: Boolean = selectorWheelPaintField.isAccessible
                        selectorWheelPaintField.isAccessible = true
                        (selectorWheelPaintField.get(this) as Paint).color = color
                        selectorWheelPaintField.isAccessible = accessible
                        invalidate()
                        val selectionDividerField: Field = this.javaClass.getDeclaredField("mSelectionDivider")
                        accessible = selectionDividerField.isAccessible()
                        selectionDividerField.isAccessible = true
                        selectionDividerField.set(this, null)
                        selectionDividerField.isAccessible = accessible
                        invalidate()
                    } catch (ignore: Exception) { }
                }
            }
        } else {
            textColor = color
        }
    }
    

    【讨论】:

      【解决方案11】:

      使用我的 NumberPicker library 很容易。

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

      【讨论】:

        猜你喜欢
        • 2016-03-06
        • 1970-01-01
        • 2014-08-05
        • 2013-09-19
        • 1970-01-01
        • 2016-03-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多