web-dev-qa-db-de.com

Datepicker-Dialog ohne Kalendervisualisierung im Lollipop [Spinner-Modus]?

Ich habe die Dokumentation gelesen: http://developer.Android.com/guide/topics/ui/controls/pickers.html Aber jetzt erscheint in Lollipop der Kalender (es ist ok für ein Ereignis, aber fürchterlich ein Geburtsdatum festlegen, würde ich einen Spinner-Modus einstellen.) und ich kann es nicht entfernen! In Layout ist es einfach mit dieser Eigenschaft: 

 <DatePicker
 datePickerMode="spinner"...>

aber vom Code des DatePickerDialogs, wenn ich versuche zu setzen

dialogDatePicker.getDatePicker().setSpinnersShown(true);
dialogDatePicker.getDatePicker().setCalendarViewShown(false); 

Diese Eigenschaften funktionieren nicht und der Kalender wird weiterhin angezeigt!

public static class MyDatePicker extends DialogFragment implements DatePickerDialog.OnDateSetListener {
        int pYear;
        int pDay;
        int pMonth;

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            // Use the current date as the default date in the picker
            final Calendar c = Calendar.getInstance();
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH);
            int day = c.get(Calendar.DAY_OF_MONTH);
            DatePickerDialog dialogDatePicker = new DatePickerDialog(getActivity(), this, year, month, day);
            dialogDatePicker.getDatePicker().setSpinnersShown(true);
            dialogDatePicker.getDatePicker().setCalendarViewShown(false);
            return dialogDatePicker;
            // Create a new instance of DatePickerDialog and return it
            //return new DatePickerDialog(getActivity(), this, year, month, day);
        }

        public void onDateSet(DatePicker view, int year, int month, int day) {
            pYear = year;
            pDay = day;
            pMonth = month;
        }
    }
33
Evilripper

DatePickerDialog verwendet das von Ihrem Aktivitätsdesign angegebene Dialogdesign. Hierbei handelt es sich um ein vollständig festgelegtes Thema. Dies bedeutet, dass Sie alle Attribute (z. B. den Datumsauswahlstil), die Sie im Aktivitätsdesign festgelegt haben, erneut angeben müssen.

<style name="MyAppTheme" parent="Android:Theme.Material">
    <item name="Android:dialogTheme">@style/MyDialogTheme</item>
    <item name="Android:datePickerStyle">@style/MyDatePicker</item>
</style>

<style name="MyDialogTheme" parent="Android:Theme.Material.Dialog">
    <item name="Android:datePickerStyle">@style/MyDatePicker</item>
</style>

<style name="MyDatePicker" parent="Android:Widget.Material.DatePicker">
    <item name="Android:datePickerMode">spinner</item>
</style>

Hinweis: Aufgrund von Problem 222208 wird dies in Android N/API 24 nicht funktionieren. Es wurde in der Plattform für die nächste Version bereits behoben. Für API 24-Geräte ist keine Problemumgehung verfügbar.

45
alanv

Wenden Sie das Holo_theme in der Codeebene an, die für mich bearbeitet wurde.

new DatePickerDialog(getActivity(),Android.R.style.Theme_Holo_Dialog,this, year,month, day);
35
Nithin Raja

Ich denke, die beste Lösung für dieses Problem ist, einen neuen Stil in der XML-Datei zu definieren und ihn dann programmgesteuert im Code zu verwenden.

Obwohl @alanv answer perfekt ist und korrekt funktionieren wird, besteht das Problem darin, dass es für alle Date-Picker angewendet wird. Angenommen, Sie haben einen DatePicker, in dem Sie die Kalenderansicht anzeigen müssen, und einen anderen DatePicker, in dem Sie die Spinneransicht anzeigen müssen. Dies funktioniert nicht. 

Definieren Sie also einen neuen Stil in einer styles.xml. Erstellen Sie diese Datei in einem Ordner mit dem Namen values-v21 (siehe Namensstruktur hier ), da diese Attribute nur nach Lollipop eingeführt werden. Vor Lollipop gab es nur den Spinner-Modus.

 <style name="CustomDatePickerDialogTheme" parent="Android:Theme.Material.Light.Dialog">
    <item name="Android:datePickerStyle">@style/MyDatePickerStyle</item>
</style>

<style name="MyDatePickerStyle" parent="@Android:style/Widget.Material.DatePicker">
    <item name="Android:datePickerMode">spinner</item>
</style>

Und schließlich verwenden Sie es im Code so

DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(),
    R.style.CustomDatePickerDialogTheme, this, year, month, day);
return datePickerDialog;
12

Fügen Sie das Attribut calendarViewShown hinzu und setzen Sie es auf false:

<DatePicker
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:id="@+id/date_field"
Android:calendarViewShown="false"/>
9
Carlos Espinoza

Sie können eine Bibliothek verwenden, um den alten "Spinner" -Stil DatePicker zu erstellen, der aus nur drei NumberPicker zusammengesetzt ist:

https://github.com/drawers/SpinnerDatePicker

 spinner date picker

Zuerst definieren Sie einen Stil:

<style name="NumbePickerStyle">
    <item name="Android:textSize">22dp</item>
    <item name="Android:textColorPrimary">@color/colorAccent</item>
    <item name="Android:colorControlNormal" tools:targetApi="Lollipop">@color/colorAccent</item>
</style>

Dann, 

new SpinnerDatePickerDialogBuilder()
        .context(MainActivity.this)
        .callback(MainActivity.this)
        .spinnerTheme(spinnerTheme)
        .year(year)
        .monthOfYear(monthOfYear)
        .dayOfMonth(dayOfMonth)
        .build()
        .show();

Haftungsausschluss: Ich bin der Autor dieser Bibliothek

8
David Rawson

Kannst du das versuchen?

DatePickerDialog dialogDatePicker = new DatePickerDialog(getActivity(), this, year, month, day);
            dialogDatePicker.getDatePicker().setCalendarViewShown(false);
            return dialogDatePicker;

entfernen 

dialogDatePicker.getDatePicker().setSpinnersShown(true);
2
Fahim

Wenn Sie alles andere als fantastische Sachen beiseite legen, verwenden Sie den DatePickerDialog-Konstruktor, der einen "int theme" -Parameter übernimmt . Ohne ihn scheint es standardmäßig auf denjenigen zu setzen, der int in den CalendarView-Modus setzt. 3 ...) Sie erhalten einen Spinner (zumindest in meiner API 19-App, die auf einem Emulator ausgeführt wird). Im Allgemeinen versuchen Sie es mit New DatePickerDialog (getContext (), 0, this, year, month, day.) ) Beachten Sie die 0 (oder 1 oder 2 usw.)

Achtung: Ich bin nicht sicher, ob es irgendwo eine Liste von statischen Themenfeldern gibt und eine hartcodierte "0" anstelle von "Theme.HOLO_LIGHT" oder was auch immer einen Unterschied auf den verschiedenen Geräten ausmachen kann, aber die Aufgabe ist erledigt irgendwie.

2
plainOldNerd

DatePicker-Methoden, die sich auf die Darstellung der Spinner- und/oder Kalenderansicht beziehen, werden von der API-Ebene 24 nicht mehr unterstützt. Die Methode setSpinnersShown (boolean) und setCalendarViewShown (boolean) werden nicht mehr unterstützt, da der Materialstil im Kalendermodus nicht unterstützt wird.

Wenn Sie den Materialstil im Drehmodus verwenden möchten, verwenden Sie das DatePicker-Widget.

Wenden Sie unten auf Ihr Date-Picker-XML-Element einen Stil an, um Material-Spinner zu erhalten. Weitere Informationen zu Datumsauswahl und Formatvorlagen finden Sie unter http://www.zoftino.com/Android-datepicker-example .

<style name="MyDatePickerSpinnerStyle" parent="@Android:style/Widget.Material.DatePicker">
    <item name="Android:datePickerMode">spinner</item>
    <item name="Android:calendarViewShown">false</item>
    <item name="colorControlNormal">#d50000</item>
</style>
1
Arnav Rao

Versuchen Sie dies, es hat für mich funktioniert, machen Sie einen benutzerdefinierten Datenspeicher:

    @SuppressWarnings("deprecation")
    public void setDate(View view) {
        showDialog(999);
    }

    @SuppressWarnings("deprecation")
    protected Dialog onCreateDialog(int id) {
        // TODO Auto-generated method stub
        if (id == 999) {
            return new DatePickerDialog(this, myDateListener, year, month-1, day);
        }
        return null;
    }
    //THIS
    private DatePickerDialog.OnDateSetListener myDateListener= new DatePickerDialog.OnDateSetListener() {

        @Override
        public void onDateSet(DatePicker arg0, int arg1, int arg2, int arg3) {

            showDate(arg1, arg2+1, arg3);
        }
    };

    private void showDate(int year, int month, int day) {

        //dateView.setText(new StringBuilder().append(day).append("-")
               // .append(month).append("-").append(year));
    }
1
MarcS

Diese Antwort ist etwas abseits, bietet jedoch einen alternativen Ansatz mit dem Standard DatePicker, der für jemanden nützlich sein kann.
Es ist jetzt 2019 und dieses Problem bleibt bestehen.

  • Android:datePickerMode="spinner" funktioniert nicht bei allen APIs
  • Die Integration einer Bibliothek für eine so einfache Aufgabe (mit einer ganz schönen Materialauswahl) ist nicht das, was jeder Entwickler will.

Von einem anderen Standpunkt aus ist das Widget sehr praktisch, das Problem ist, dass nicht alle Android-Benutzer wissen, dass sie den Abschnitt zur Jahresauswahl öffnen können, wodurch die Auswahl des Jahres vereinfacht wird:

 enter image description here

Dies schafft nicht die beste UX für einige Benutzer und sie haben schwere Zeiten mit der Auswahl des Geburtsdatums (einige Benutzer streichen den Kalender nur bis zum gewünschten Jahr).

Am Ende gab es eine Lösung für die Problemumgehung, mit der Sie Folgendes tun können:

  1. Zeigt zunächst die Benutzerjahres-Auswahlansicht des DatePicker an (Bild oben), woraufhin er zur Kalenderansicht navigiert
  2. Oder zeigen Sie eine normale Kalenderansicht an, mit Hervorhebung der Schaltfläche "Jahr" mit der Ripple (oder auf andere Weise, z. B. der Hintergrund des Jahres, damit es wie eine Schaltfläche wirkt). 

In der Animation unten sehen Sie, wie verschiedene Lösungen für einen Benutzer sichtbar sind: 

 enter image description here

Was Sie brauchen:

  1. Zeigen Sie eine DatePicker (DatePickerDialog oder eine DialogFragment, die es erstellt).
  2. Rufen Sie das "Jahr" TextView ab:

    val yearTextview =dialog.findViewById<TextView>(context.resources
    ?.getIdentifier("Android:id/date_picker_header_year", null, null)?: -1)
    
  3. Machen Sie, was Sie wollen, zum Beispiel:

    • Führen Sie einen Klick programmgesteuert aus, um einen Jahresabschnitt auszuwählen:

    yearTextview? .performClick ()

    • Ripple-Effekt nach dem Anzeigen anzeigen (mit der Einstellung yearTextview?.isPressed = true für einige Zeit)

    • Ändern Sie den Hintergrund usw.

Nachteil: Wenn die ID in den nächsten APIs geändert wird, müssen Sie sie entsprechend ändern

0
Leo Droidcoder