it-swarm.com.de

Android: Wie ändere ich die Farbe des Datepicker-Teilers?

Ich habe eine Datumsauswahl in meiner Android-App, aber jetzt möchte ich die Farbe der blauen Trennwände in Grün ändern (siehe das Bild unter diesem Text). Es gibt einigeandereDiskussionen auf Stackoverflow, die über dasselbe sprechen, aber keiner von ihnen gibt eine Antwort, die zu einer Lösung führt.

Also habe ich mich selbst gesucht und festgestellt, dass es tatsächlich ein Android: datePickerStyle gibt und es gibt auch einen Android: Divider. Ich weiß jedoch nicht, ob sich der Teiler tatsächlich auf den Teiler in der Datumsauswahl bezieht. Ich habe eine Vielzahl von Kombinationen aus den beiden ausprobiert, aber ich scheine es nicht zu schaffen. Also meine erste Frage: Bezieht sich der Android: divider auf den divider im datepicker und wie kann ich damit die Farbe ändern?

Eine andere Möglichkeit ist also die Erstellung eines völlig neuen benutzerdefinierten Datepickers. Wenn ich so die Farbe des Teilers ändern kann, bin ich dafür. Ich habe mir einigeofthetutorials beim Erstellen eines benutzerdefinierten Datepickers angesehen, aber keiner von ihnen scheint die Farbe von zu definieren die Teiler. Die Teiler werden einfach nicht in den XML-Dateien oder in den Java-Dateien aufgeführt.

Es wäre großartig, wenn es eine Art Boilerplate-Code geben würde, um das Datumsfenster neu zu erstellen, wie es gerade angezeigt wird, einschließlich des Codes, der die Farbe der Trennwände festlegt. Hoffentlich könnte ich das kopieren und einfach die Farbe des Teilers irgendwo ändern. Also meine zweite Frage: Weiß jemand einen Boilerplate-Code, der einfach den Datepicker so implementiert, wie er jetzt ist (einschließlich einer Definition der Teiler)?

enter image description here

35
kramer65

Leider ist dies keine triviale Aufgabe.

DatePickers Widgets NumberPicker und CalendarView intern verwenden. Das von Ihnen veröffentlichte Bild verwendet beispielsweise 3 NumberPickers. Und die Trennlinien, von denen Sie sprechen, stammen aus dem NumberPicker-Attribut: selectionDivider. Das Problem ist, dass dieses Attribut nicht öffentlich ist und numberPickerStyle, über das dieses Attribut festgelegt wird.

Ich habe vor kurzem CalendarView und NumberPicker auf API 8 zurückportiert, hauptsächlich zum Spaß. Da der Code leicht verfügbar ist (schauen Sie sich Android.widget.NumberPicker und andere in der Android-Quelle an), ist für diese Aufgabe nur Zeit erforderlich, und einige durchsuchen den Quellcode von Android. Beispiele:

  1. Einfach ==> Sie müssen die private Variable von der View-Klasse in ihre Accessor-Methoden ändern

    mLeft (geschützte Variable in der View-Klasse) ==> getLeft () (öffentliche Zugriffsmethode)

  2. Die zeitaufwändigste Aufgabe war die Wiederherstellung der Eingabehilfen.

In jedem Fall müssen Sie die benutzerdefinierten Implementierungen von DatePicker (optional) auch für NumberPicker und CalendarView schreiben.

Einfacher:

Backported DatePicker ist hier als Bibliothek verfügbar: Android-DatePicker . Wie oben erwähnt, verwenden Sie backported CalendarView und NumberPicker in Verbindung mit diesem DatePicker.

Was Sie ändern müssen:

Verwenden Sie {library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.png als Vorlage und ändern Sie die 'bläuliche' Farbe in grün (ich habe pixlr ). Sie können ihn entweder unter demselben Namen speichern, wenn Sie den blauen Teiler vollständig verwenden möchten, oder Sie können einen anderen Namen verwenden und Änderungen in {library-numberpicker} / res / values / themes.xml vornehmen.

Die in themes.xml erforderlichen Änderungen, wenn Sie einen anderen Namen wählen:

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

Und das ist es.

Ausgabe mit den Bibliotheken:

enter image description here

Bearbeiten:

Bezieht sich der Android:divider auf den Teiler in der Datumsauswahl und wie könnte ich ihn verwenden, um die Farbe zu ändern?

Das Attribut divider stammt tatsächlich von LinearLayout. NumberPicker erbt dieses Attribut als NumberPicker extends LinearLayout. Aber dieses divider dient einem anderen Zweck. Das an dieses Attribut übergebene Drawable wird zwischen den untergeordneten Ansichten von LinearLayout platziert.

Das Attribut Android:showDividers wird verwendet, um die Platzierung dieses Teilers zu ändern. Mögliche Werte sind:

  • none: Es werden keine Trennlinien angezeigt
  • anfang: Teiler wird vor der ersten untergeordneten Ansicht angezeigt
  • mitte: Teiler wird nach jeder untergeordneten Ansicht angezeigt, nicht nach der letzten untergeordneten Ansicht
  • ende: Teiler wird nach der letzten untergeordneten Ansicht angezeigt

Das Attribut Android:dividerPadding ist selbsterklärend.

Obwohl NumberPicker dieses Attribut erbt, wird es nicht verwendet. Dies geht aus Ihren eigenen Forschungen und Versuchen hervor: I tried a multitude of combinations of the two, but I don't seem to get it to work.

So zeigen Sie das Divider-Attribut in Aktion an:

<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>

Hack-ish Workaround mit Java Reflection:

Diese Antwort hier brachte mich auf die Idee. Ich hasse es, Refektion im Allgemeinen zu verwenden, hauptsächlich aus den in dieser Antwort aufgeführten Gründen: Link . Obwohl ich es der Vollständigkeit halber hier aufführe, schlage ich vor , dass Sie es nicht verwenden.

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();
        }
    }
}

Was wir hier machen:

  • DatePicker erweitern
  • Wenn Sie date_picker.xml in sdk/platforms/Android-xx/res/layout öffnen, werden Sie feststellen, dass die drei NumberPickers die IDs month, day, year haben. Wir greifen auf Android.internal.R.id zu, um Ressourcen-IDs für diese NumberPickers abzurufen.
  • Mit diesen IDs erstellen wir drei NumberPicker-Objekte mit der findViewById(int) -Methode.
  • Greifen Sie dann auf das Feld mSelectionDivider zu und rufen Sie es mit relection ab.
  • Setzen Sie das Feld auf barrierefrei (als deklariertes Final) und setzen Sie seinen Wert mit der Methode Field#set(Object, Object). Das erste Argument ist das Objekt, für das wir diese Operation ausführen. Das zweite Argument ist das Objekt, das wir festlegen möchten.

Das von mir verwendete Drawable kann von folgender Adresse heruntergeladen werden: hier .

100
Vikram

Ich denke, die einfachste Lösung ist wahrscheinlich, Stile zu verwenden.

Fügen Sie dies einfach in Ihr styles.xml-Dokument ein

    <!-- 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>

und fügen Sie diese Attribute in Ihre Layout-XML ein

Android:theme="@style/appCompatStyle"

und passen Sie es an, wie Sie möchten.

22
JCLaHoot

Es gibt eine bibliothek Sie haben Zeit- und Datumsauswahl. Sie können die Farbe des Teilers folgendermaßen ändern

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

Edit Eine andere library habe ich auch verwendet, was auch gut ist, da Sie sie in thems.xml folgendermaßen anpassen können

<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

Wenn Sie ein Design auf DatePicker layout setzen und colorControlNormal hinzufügen, funktioniert das für mich.

Fügen Sie in der XML-Datei Ihres Layouts eine DatePicker hinzu, indem Sie ein Design wie unten gezeigt anwenden. 

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

und definieren Sie dann die NumberPickerStyle in styles.xml, indem Sie colorControlNormal wie folgt angeben:

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

Zuerst; Vikram, du hast großartige Arbeit geleistet, danke für deine Mühe! Eine Sache, die mir in net.simonvt.datepicker.DatePickerDialog fehlte, war die Option, die titleDivider-Farbe festzulegen, die ich mit numberPickerDividerColor abgleichen möchte. Also habe ich diese Option in die Vikrams-Implementierung eingefügt und poste sie hier. Dies ist eine gängige Lösung für das Ändern von AlertDialog.titleDividerColor. Vielleicht hilft es jemandem.

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

Es ist wichtig, die Farbe festzulegen, wenn der Dialog angezeigt wird. Ich mache dies in der onAttachedToWindow-Methode.

@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

Ich habe hier eine andere Lösung veröffentlicht https://stackoverflow.com/a/33800696/1134335

0
GMan

Um nur die Teilerfarbe in DatePickerDialog zu ändern, genügt es, den Android: datePickerDialogTheme-Stil in Ihrem Design zu ändern: 

Themenstil:

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

Dialogstil:

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