web-dev-qa-db-ja.com

NumberPickerのテキストの色を変更します

私はこれに関するほとんどすべてのスレッドを見てきましたが、どれも有効な答えを提供しませんでした。 NumberPickerのスタイル設定は機能しません(このスレッドごとに NumberPicker textColour

NumberPickerのスタイル属性をカラーアイテムを持つスタイルに設定しても、効果はありません。また、numberPicker XMLのtextColor属性を設定しても何も起こりません。

これに最も近いのは、numberPickerを使用してgetChildAt()をEditTextにキャストしてから、そのEditTextでsetColor()を実行することです。その上;私が探しているものではありません。

何か助け?ありがとう

41
Odaym

このコードは問題を解決するはずです。発生する問題は、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();  
}
71
Simon

私が試し、私のために働いた解決策は次のとおりです。

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

なぜJava Reflection APIに飛び込む必要があるのか​​わかりません。そのシンプルなスタイリングの問題です。オーバーライドする必要がある属性はtextColorPrimaryです。

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

TimePicker内でDialogを使用している場合は、ダイアログのテーマでAndroid:textColorPrimaryをオーバーライドします。

それについてです。

追加情報:

Yoann Hercouet による洞察力に富んだコメントです:

このソリューションは、NumberPickerの色のみを変更するのではなく、多くのコンポーネントに影響を与えるグローバルな変更です

これは正しいですが、私が示唆している可能性を見落としています。さらに、globalはアプリ全体の影響を意味します。 NumberPickerを含むアクティビティにのみこのテーマを適用することにより、アクティビティスコープに限定できます。しかし、私は同意します、これはまだ腐食性かもしれません。

ここでのアイデアは、NumberPickerで表示されるテーマにtextColorPrimary=INTENDED_COLORを何らかの形で挿入することです。これを実現する方法は複数あります。 1つの方法を次に示します。

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がアプリに与える影響を抑制しました。

これはもちろん1つのオプションにすぎません。たとえば、NumberPickerを含むレイアウトを拡張する場合、次を使用できます。

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

上記の回答のTextSizeとTextStyle Boldを使用した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;
    }
7
Andreas Merz

@ 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();
            }
        }
    }
}
2
Eduardo Reis

すべてのテキストの色を希望の色に変更する代わりに、すべてのeditTextの色を変更することをお勧めします。 NumberPickerには、実際に数字を表示する子EditTextがあります。

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

これは私のために働いた。また、ボタンに白いテキストがありますが、変更されていません。

1
Dinidiniz

受け入れられた答えは非常に複雑です。私のために働いたはるかに簡単なアプローチは、使用していたテーマのtextColorPrimary属性をオーバーライドすることでした。

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

それは非常にうまく仕事をしました!

1
mgm

私のテーマでAndroid:textColorPrimaryを設定しても何もしませんでした。NumberPickerのソースコードを見て、EditText入力からテキストの色を決定するので、Android:editTextColor代わりに。

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

Android SDK> = 29のリフレクション拒否に基づいて、Simonの答えを修正する方が良い:

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()メソッドがあります。

0
Tapa Save