web-dev-qa-db-ja.com

Android:デイトピッカーディバイダーの色を変更するには?

Androidアプリに日付ピッカーがありますが、今度は青色の仕切りの色を緑色に変更します(このテキストの下の画像を参照)。 someotherDiscussions 同じことを話すStackoverflowについては、どれも答えを出さないソリューションにつながります。

だから自分で調べてみると、実際にはAndroid:datePickerStyleがあり、Android:dividerもあることがわかりました。しかし、分周器が実際に日付ピッカーの分周器を参照しているかどうかはわかりません。 2つの組み合わせを多数試しましたが、うまくいかないようです。だから私の最初の質問:Android:dividerはdatepickerのディバイダーを参照しますか?それを使用して色を変更するにはどうすればよいですか?

したがって、別のオプションは、完全に新しいカスタム日付ピッカーを作成することです。それにより、仕切りの色を変更するだけで済むなら、私はそれのためにダウンしています。だから、 someofthetutorials カスタムdatepickerの作成についてですが、仕切りの色を定義するものはありません。区切り線は、xmlファイルまたはJavaファイルにリストされていません。

区切り線の色を設定するコードなど、現在表示されている日付ピッカーを再作成するためのボイラープレートコードがあれば素晴らしいでしょう。うまくいけば、それをコピーして、単に仕切りの色設定をどこかで変更できるようになります。だから私の2番目の質問:誰かが今のように日付ピッカーを単に実装する定型コードを知っていますか(分周器の定義を含む)?

enter image description here

36
kramer65

残念ながら、これは簡単な作業ではありません。

DatePickersは内部でウィジェットNumberPickerおよびCalendarViewを使用します。たとえば、投稿した画像は3 NumberPickersを使用しています。そして、あなたが話している仕切りは、NumberPickerの属性selectionDividerから来ています。問題は、この属性がパブリックではなく、numberPickerStyleでもないことです。これにより、この属性が設定されます。

私は最近、CalendarViewとNumberPickerをAPI 8にバックポートしました。コードはすぐに利用できるため(Androidソースの_Android.widget.NumberPicker_などを検索)、このタスクにかかる時間はすべて、Androidのソースコードを掘り下げることだけです。例:

  1. 簡単==>プライベート変数をViewクラスからそのアクセサメソッドに変更する必要があります

    mLeft(Viewクラスの保護された変数)==> getLeft()(パブリックアクセサーメソッド)

  2. 最も時間のかかるタスクは、アクセシビリティメソッドを復元することでした。

いずれにせよ、DatePickerのカスタム実装を作成することに決めた場合、NumberPickerおよびCalendarView(オプション)についても同様に記述する必要があります。

簡単な方法:

バックポートされたDatePickerは、ライブラリとして Android-DatePicker で利用できます。前述のように、このDatePickerとともにバックポートされた CalendarView および NumberPicker を使用します。

変更する必要があるもの:

_{library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.png_をテンプレートとして使用し、「青みがかった」色を緑に変更します( pixlr を使用しました)。青い仕切りをすべて使用する場合は、同じ名前で保存するか、別の名前を使用して_{library-numberpicker} / res / values / themes.xml_を変更します。

別の名前を選択した場合、_themes.xml_で必要な変更:

_<style name="NPWidget.Holo.NumberPicker" parent="NPWidget.NumberPicker">
    ....
    <item name="selectionDivider">@drawable/new_nine_path_drawable_name</item>
    ....
</style>
_

以上です。

ライブラリを使用した出力:

enter image description here

編集:

_Android:divider_はdatepickerのディバイダーを参照しますか?それを使用して色を変更するにはどうすればよいですか?

属性dividerは、実際にはLinearLayoutから取得されます。 NumberPickerは、この属性を_NumberPicker extends LinearLayout_として継承します。しかし、このdividerは別の目的を果たします。この属性に渡されるドロウアブルは、LinearLayoutの子ビューの間に配置されます。

属性_Android:showDividers_は、このディバイダーの配置を変更するために使用されます。可能な値は次のとおりです。

  • none:仕切りは表示されません
  • 開始:分周器は最初の子ビューの前に表示されます
  • 中央:最後の子ビューではなく、各子ビューの後にディバイダーが表示されます
  • end:最後の子ビューの後にディバイダーが表示されます

属性_Android:dividerPadding_は一目瞭然です。

NumberPickerはこの属性を継承しますが、使用しません。これはあなた自身の研究と試行から明らかです:_I tried a multitude of combinations of the two, but I don't seem to get it to work._

動作中のdivider属性を見るには:

_<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:orientation="horizontal"
    Android:divider="@Android:drawable/ic_media_play"
    Android:showDividers="middle" >

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Hello" />

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="World," />

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Again" />

</LinearLayout>
_

Java reflection:を使用したハック的な回避策

この答え here は私にアイデアを与えました。私は主にこの答えにリストされている理由のために、反射を使用することを嫌います: リンク 。ここでは完全を期すためにリストしていますが、私はsuggest使用しないでください。

_public class CDP extends Android.widget.DatePicker {

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

        Class<?> internalRID = null;
        try {
            internalRID = Class.forName("com.Android.internal.R$id");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        Field month = null;
        try {
            month = internalRID.getField("month");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        NumberPicker npMonth = null;
        try {
            npMonth = (NumberPicker) findViewById(month.getInt(null));
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        Field day = null;
        try {
            day = internalRID.getField("day");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        NumberPicker npDay = null;
        try {
            npDay = (NumberPicker) findViewById(day.getInt(null));
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        Field year = null;
        try {
            year = internalRID.getField("year");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        NumberPicker npYear = null;
        try {
            npYear = (NumberPicker) findViewById(year.getInt(null));
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        Class<?> numberPickerClass = null;
        try {
            numberPickerClass = Class.forName("Android.widget.NumberPicker");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        Field selectionDivider = null;
        try {
            selectionDivider = numberPickerClass.getDeclaredField("mSelectionDivider");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        try {
            selectionDivider.setAccessible(true);
            selectionDivider.set(npMonth, getResources().getDrawable(
                       R.drawable.np_numberpicker_selection_divider_green));
            selectionDivider.set(npDay, getResources().getDrawable(
                       R.drawable.np_numberpicker_selection_divider_green));
            selectionDivider.set(npYear, getResources().getDrawable(
                       R.drawable.np_numberpicker_selection_divider_green));
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
_

ここで行うこと:

  • DatePickerを拡張する
  • _date_picker.xml_を_sdk/platforms/Android-xx/res/layout_で開くと、3つのNumberPickerのIDがmonthdayyearであることがわかります。 _Android.internal.R.id_にアクセスして、これらのNumberPickersのリソースIDを取得します。
  • これらのIDとfindViewById(int)メソッドを使用して、3つのNumberPickerオブジェクトを作成します。
  • 次に、relectionを使用してField mSelectionDividerにアクセスして取得します。
  • フィールドを(最終宣言として)アクセス可能に設定し、Field#set(Object, Object)メソッドを使用して値を設定します。最初の引数は、この操作を実行するオブジェクトです。 2番目の引数は、設定するオブジェクトです。

私が使用したドローアブルは、 here からダウンロードできます。

100
Vikram

最も簡単な解決策はおそらくスタイルを使用することだと思います。

これをstyles.xmlドキュメントに入れるだけです

    <!-- changes the default colours for EditTexts, including non-text elements (also works with the DatePicker -->

<style name="appCompatStyle" parent="Theme.AppCompat.Light">
    <item name="colorControlNormal">@color/lightPrimaryText</item>
    <item name="colorControlActivated">@color/colorAccent</item>
    <item name="Android:editTextStyle">@style/editTextStyle</item>
</style>


<!-- changes the default text colour for the EditTexts -->
<style name="editTextStyle" parent="Android:style/Widget.EditText">
    <item name="Android:textColor">@color/lightPrimaryText</item>
</style>

これらの属性をレイアウトXMLに配置します

Android:theme="@style/appCompatStyle"

好きなようにカスタマイズしてください。

24
JCLaHoot

テーマをDatePickerレイアウトに設定し、colorControlNormalを追加するとうまくいきます。

レイアウトのxmlに、以下に示すようにテーマを適用するDatePickerを追加します-

<DatePicker xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:theme="@style/NumberPickerStyle"
            Android:datePickerMode="spinner"
            Android:calendarViewShown="false"
            Android:layout_gravity="center_horizontal"
            Android:layout_height="wrap_content"
            Android:layout_width="wrap_content"/>

そして、styles.xmlNumberPickerStyleを定義し、次のようにcolorControlNormalを指定します-

<style name="NumberPickerStyle">
        <item name="colorControlNormal">@color/colorAccent</item>
</style>
5
shubham1g5

library が1つあり、カスタマイズされた時刻と日付のピッカーがあります。その点で、次のように仕切りの色を変更できます

    timePicker.setSelectionDivider(new ColorDrawable(0xffff0000));
    timePicker.setSelectionDividerHeight(2);

Edit別の library また、thems.xmlで次の方法を使用してカスタマイズできるという点でも優れたものを使用しました

<style name="NPWidget.Holo.NumberPicker" parent="NPWidget.NumberPicker">
        <item name="solidColor">@Android:color/transparent</item>
        <item name="selectionDivider">@color/div_color</item>
        <item name="selectionDividerHeight">0.3dip</item>
        <item name="internalLayout">@layout/number_picker_with_selector_wheel</item>
        <item name="internalMinWidth">64dip</item>
        <item name="internalMaxHeight">140dip</item>
        <item name="virtualButtonPressedDrawable">@drawable/item_background_holo_dark</item>
    </style>
3
Rajesh Nasit

まず第一に; Vikram、あなたは素晴らしい仕事をしてくれました。あなたの努力に感謝します! net.simonvt.datepicker.DatePickerDialogで欠けていたものの1つは、titleDividerと一致させたいnumberPickerDividerColor色を設定するオプションでした。そこで、Vikramsの実装にこのオプションを追加し、ここに投稿しています。 AlertDialog.titleDividerColorの変更に関連する一般的なソリューションです。たぶんそれは誰かを助けるでしょう。

class net.simonvt.datepicker.DatePickerDialog
private int titleDividerColor;

ダイアログが表示されるときに色を設定することが重要なので、onAttachedToWindowメソッドでこれを行います。

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();

    if (titleDividerColor <= 0) { return; }

    try {
        int dividerId = getContext().getResources().getIdentifier("Android:id/titleDivider", null, null);
        View divider = findViewById(dividerId);
        if (divider != null) {
            divider.setBackgroundColor(getContext().getResources().getColor(titleDividerColor));
        }
    } catch (Exception e) {}
}

public void setTitleDividerColor(int titleDividerColor) {
    this.titleDividerColor = titleDividerColor;
}

public int getTitleDividerColor() {
    return titleDividerColor;
}

[〜#〜] edit [〜#〜]

ここに別のソリューションを投稿しました https://stackoverflow.com/a/33800696/1134335

0
GMan

DatePickerDialogの分割色のみを変更するには、テーマのAndroid:datePickerDialogThemeスタイルを変更するだけで十分です。

テーマスタイル:

 <style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="Android:datePickerDialogTheme">@style/style_date_picker_dialog</item>
</style>

ダイアログスタイル:

<style name="style_date_picker_dialog" parent="AppCompatAlertDialogStyle">
<item name="colorControlNormal">@color/colorAccent</item>
</style>