如何在安卓中更改数字选择器的样式?

18
我想使用NumberPicker组件小部件,但是我需要将默认的Holo主题中的蓝色替换为橙色,因为这是我的样式中的默认颜色。我该如何替换蓝色和数字的颜色,并保留组件的所有功能? 谢谢 Holo中的默认数字选择器

1
为什么Google不允许样式化NumberPicker? - Eugen Martynov
5个回答

25
很遗憾,您无法对其进行样式设置。 NumberPicker 的样式和样式属性不存在于公共API中,因此您无法设置它们并更改默认外观。 您只能在浅色和深色主题之间进行选择。
作为解决方案,我建议使用 android-numberpicker 库。 该库基本上是从Android源代码中提取出的NumberPicker端口。 但它比那更好,它还将 NumberPicker 回退到Android 2.x。 该库可以轻松地进行样式设置。
要调整分隔线的样式,请调整NPWidget.Holo.NumberPicker样式及其selectionDividerselectionDividerHeight属性。
要调整文本的样式,请调整NPWidget.Holo.EditText.NumberPickerInputText样式。

但是使用您建议的库后,组件的滚动功能丢失了,我真的很想保留这个功能。 - user1796624
库版本也可以滚动。没有问题。 - Tomik
1
无论我选择什么样式,我总是得到黑色的文本。 - Someone Somewhere
@SomeoneSomewhere 旧评论,我知道。您需要在基础主题中覆盖 android:textColorPrimary。这可能会影响其他 TextView 的文本颜色(如果没有显式设置)。但是,此行为可以在 Activity 级别上进行控制。 - Vikram
如果这个库也不能自行设置文本样式,那它有什么用呢?我已经按照不同的方式覆盖了android:textColorPrimary,所以我无法再次覆盖它。 - SlashG
添加说明,公共属性是通过框架使用此res/values/public.xml进行标记的。此外,这里还有更多关于它如何工作的上下文信息 - Pedro Lopes

10

自定义数字选择器的预览:

在此输入图片描述

<NumberPicker
  android:id="@+id/np"
  android:layout_width="40dp"
  android:layout_height="40dp"
  android:layout_centerHorizontal="true"
  android:background="@drawable/drawablenp"
  android:layout_centerVertical="true"/>

在drawable文件夹中创建名为"drawablenp.xml"的背景xml文件。

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <gradient
        android:startColor="#707070"
        android:centerColor="#f8f8f8"
        android:endColor="#707070"
        android:angle="270"/>

</shape>

2
我也遇到了这个问题。我真的想要一个漂亮的NumberPicker UI。虽然这个问题中的所有答案都可以工作,但是它们非常有限。我几乎创建了自己的RecylerView来创建我想要的NumberPicker。显然,我找到了一个很棒的库,非常强大。这是链接:https://github.com/Carbs0126/NumberPickerView 不是在此回答问题。只是想帮助有同样问题的人。

2

复制library/res/drawable-*/numberpicker_selection_divider.9.png并将其命名为custom_np_sd.9.png。

通过活动主题覆盖默认的NumberPicker样式:

<style name="AppTheme" parent="@style/Holo.Theme">
  <item name="numberPickerStyle">@style/CustomNPStyle</item>
</style>
<style name="CustomNPStyle" parent="@style/Holo.NumberPicker">
  <item name="selectionDivider">@drawable/custom_np_sd</item>
</style>

并将@style/AppTheme应用为活动主题。


4
我该在哪里找到库文件夹以便复制样式? - user1796624
6
错误:无法检索项目父级,找不到与给定名称“@ android:style/Widget.Holo.NumberPicker”相匹配的资源。错误:找不到与给定名称匹配的资源:attr'android:selectionDivider'。 - zdarsky.peter
我同意上面的评论。找不到任何资源。如何使用它? - maXp

1

我也遇到了这个问题,我使用反射来改变样式。

public class MyNumberPicker extends NumberPicker {
    public MyNumberPicker(Context context) {
        super(context);

        setNumberPickerDivider();
    }

    public MyNumberPicker(Context context, AttributeSet attrs) {
        super(context, attrs);

        setNumberPickerDivider();
    }

    public MyNumberPicker(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        setNumberPickerDivider();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public MyNumberPicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        setNumberPickerDivider();
    }

    @Override
    public void addView(View child) {
        super.addView(child);
        updateView(child);
    }

    @Override
    public void addView(View child, int index, android.view.ViewGroup.LayoutParams params) {
        super.addView(child, index, params);
        updateView(child);
    }

    @Override
    public void addView(View child, android.view.ViewGroup.LayoutParams params) {
        super.addView(child, params);
        updateView(child);
    }

    public void updateView(View view) {
        if (view instanceof EditText) {
            EditText et = (EditText) view;
            et.setTextColor(ContextCompat.getColor(getContext(), R.color.font_content));
            et.setTextSize(16);
        }
    }

    private void setNumberPickerDivider() {

        try {
            {
                Field field = NumberPicker.class.getDeclaredField("mSelectionDivider");
                field.setAccessible(true);
                field.set(this, ContextCompat.getDrawable(getContext(), R.drawable.horizontal_divider));
            }

            {
                Field field = NumberPicker.class.getDeclaredField("mSelectionDividerHeight");
                field.setAccessible(true);
                field.set(this, 1);
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

不支持28及以上的API。https://developer.android.com/about/versions/10/non-sdk-q?authuser=1 - AlexS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接