web-dev-qa-db-ja.com

NumberPickerディバイダーの色の変更

最近のAndroid=バージョン、 番号ピッカー 描画時に青い区切り線を使用します(下の画像を参照)。

enter image description here

この色を変えたいです。実用的なソリューションはありますか?または、区切り線の色をカスタマイズできるNumberPickerの更新バージョンをパッケージ化したライブラリでしょうか?

Android-numberpicker を試しましたが、存在しないリソースIDにアクセスしようとするライブラリのコードが原因で、実行時にエラーが発生します(以下を参照)。

Android.content.res.Resources$NotFoundException: Resource ID #0x0
        at Android.content.res.Resources.getValue(Resources.Java:1123)
        at Android.content.res.Resources.loadXmlResourceParser(Resources.Java:2309)
        at Android.content.res.Resources.getLayout(Resources.Java:939)
        at Android.view.LayoutInflater.inflate(LayoutInflater.Java:395)
        at net.simonvt.numberpicker.NumberPicker.<init>(NumberPicker.Java:635)
        at net.simonvt.numberpicker.NumberPicker.<init>(NumberPicker.Java:560)
        at net.simonvt.numberpicker.NumberPicker.<init>(NumberPicker.Java:550)
33
Laurent

これに基づいて( https://stackoverflow.com/a/20291416/291548 DatePickerについてですが)いくつかの方法があります:

  1. MSelectionDividerとその関連会社なしで独自のNumberPickerを作成するか、 Vikram によってバックポートされたものを使用します。最後の場合:

    1. github からlibからダウンロード
    2. res/drawable-xxx/np_numberpicker_selection_divider.9.pngのドロアブルを変更します。

      • 透明(または何でも).9.png
      • res/drawableにnp_numberpicker_selection_divider.xmlシェイプラインリソースを作成します(_0dp_高さまたは透明色を使用)。
    3. または NumberPicker.Java like here のonDraw(Canvas)メソッドからif (mSelectionDivider != null)ブランチを削除します

  2. リフレクションを使用して_private final field mSelectionDivider_にアクセスします(詳細: https://github.com/Android/platform_frameworks_base/blob/master/core/Java/Android/widget/NumberPicker.Java )-例変更を参照してください こちら 。私はリフレクションを使用しましたが、それは最良の解決策ではありません。

18

単に色を変更したい場合(スタンナムの回答に基づいて):

private void setDividerColor(NumberPicker picker, int color) {

    Java.lang.reflect.Field[] pickerFields = NumberPicker.class.getDeclaredFields();
    for (Java.lang.reflect.Field pf : pickerFields) {
        if (pf.getName().equals("mSelectionDivider")) {
            pf.setAccessible(true);
            try {
                ColorDrawable colorDrawable = new ColorDrawable(color);
                pf.set(picker, colorDrawable);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (Resources.NotFoundException e) {
                e.printStackTrace();
            }
            catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            break;
        }
    }
}

それとその後

setDividerColor(mNumberPicker, Color.GREEN);
59
gabin

これは反射を使用せずに私のために働いた。

my_layout.xml

<NumberPicker
   ...
   Android:theme="@style/DefaultNumberPickerTheme" />

Styles.xml(AppThemeはアプリ内のアプリのテーマです)

<style name="DefaultNumberPickerTheme" parent="AppTheme">
        <item name="colorControlNormal">@color/dividerColor</item>
</style>
43
Rubin Yoo

私は回避策を使用していますJava method:

  private void setDividerColor (NumberPicker picker) {   

        Java.lang.reflect.Field[] pickerFields = NumberPicker.class.getDeclaredFields();
        for (Java.lang.reflect.Field pf : pickerFields) {
            if (pf.getName().equals("mSelectionDivider")) {
                pf.setAccessible(true);
                try {
                    //pf.set(picker, getResources().getColor(R.color.my_orange));
                    //Log.v(TAG,"here");
                    pf.set(picker, getResources().getDrawable(R.drawable.dot_orange));
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (NotFoundException e) {
                    e.printStackTrace();
                } 
                catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
        //}
     }

またはKotlinメソッド:

private fun NumberPicker.setDividerColor(color: Int) {
    val dividerField = NumberPicker::class.Java.declaredFields.firstOrNull { it.name == "mSelectionDivider" } ?: return
    try {
       dividerField.isAccessible = true
       dividerField.set(this,getResources().getDrawable(R.drawable.dot_orange))
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

そして、その適用

  setDividerColor(yourNumberPicker); // for Java method
  yourNumberPicker.setDividerColor(Color.RED) // for kotlin method
12
stannums

私はAndroidが初めてなので、この解決策は良い方法ではないかもしれないことを心に留めておいてください。

2つの細い水平ビューをViewGroupに追加し、負のレイアウトマージンと背景に希望する色を与えることで、LinearLayout内のNumberPickerのディバイダーの色を「変更」できました。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="horizontal"
    Android:layout_gravity="center_horizontal"
    Android:gravity="center"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    >
    <NumberPicker
        Android:layout_width="70dip"
        Android:layout_height="wrap_content"
        Android:focusable="true"
        Android:focusableInTouchMode="true"
        Android:layout_gravity="center"
        Android:layout_margin="5dp"
        />

    <View
        Android:layout_height="2dp"
        Android:layout_width="70dp"
        Android:background="@color/myColor"
        Android:layout_gravity="center_vertical"
        Android:layout_marginLeft="-75dp"
        Android:layout_marginBottom="-25dp">

    </View>

    <View
        Android:layout_height="2dp"
        Android:layout_width="70dp"
        Android:background="@color/myColor"
        Android:layout_gravity="center_vertical"
        Android:layout_marginLeft="-70dp"
        Android:layout_marginBottom="25dp">

    </View>

</LinearLayout>

確かに、実際に色を変更するのではなく、組み込みの仕切りの上に希望の色の新しい線を追加します。とにかく、これが誰かを助けることを願っています!

余白で遊ぶ必要があるかもしれませんが、これらの設定は私のカスタムダイアログに最適でした。

3
JDune

リフレクションを使用してトリックを行うことができます。ここに私の解決策があります

public class ColorChangableNumberPicker extends NumberPicker {

    public ColorChangableNumberPicker(Context context) {
        super(context);
        init();
    }

    public ColorChangableNumberPicker(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ColorChangableNumberPicker(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @TargetApi(Build.VERSION_CODES.Lollipop)
    public ColorChangableNumberPicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {
        setDividerColor(Color.RED);
    }


    public void setDividerColor(@ColorInt int color) {
        try {
            Field fDividerDrawable = NumberPicker.class.getDeclaredField("mSelectionDivider");
            fDividerDrawable.setAccessible(true);
            Drawable d = (Drawable) fDividerDrawable.get(this);
            d.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
            d.invalidateSelf();
            postInvalidate(); // Drawable is dirty
        }
        catch (Exception e) {

        }
    }
}
2
Bojan Kseneman

以下のコードを使用して、直接色ではなく分割線を変更しますが、png like this で変更できます。

このソリューションは here に由来しますが、私のコードは分周器を変更する簡単な単純化であり、それだけです。

    // change divider
    Java.lang.reflect.Field[] pickerFields = NumberPicker.class
            .getDeclaredFields();
    for (Java.lang.reflect.Field pf : pickerFields) {
        if (pf.getName().equals("mSelectionDivider")) {
            pf.setAccessible(true);
            try {
                pf.set(spindle, getResources().getDrawable(R.drawable.np_numberpicker_selection_divider_green));
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (NotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            break;
        }
    }
1
SerSánGal

library (私もNumberPickerをロールバックしました)を使えば簡単です。

<com.github.tomeees.scrollpicker.ScrollPicker
    ...
    app:selectorColor="..."
    />
0
Tamás Sajti

将来分割線の色を変更する場合は、プライベートフィールドを保存することをお勧めします。このような:

@Nullable private Field dividerField;

public void setDivider(@Nullable Drawable divider) {
    try {
        if (dividerField == null) {
            dividerField = NumberPicker.class.getDeclaredField("mSelectionDivider");
            dividerField.setAccessible(true);
        }

        dividerField.set(this, divider);
    } catch (Exception ignore) {}
}
0
0neel

このコードを使用して、分周器でやりたいことをすべて行います

Field[] pickerFields = NumberPicker.class.getDeclaredFields();
            for (Field pf : pickerFields) {
                if (pf.getName().equals("mSelectionDivider")) {
                    pf.setAccessible(true);
                    try {
                        pf.set(picker, getResources().getDrawable(R.drawable.divider));
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (NotFoundException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
0