Android: jak zmienić kolor dzielnika datepicker?

Mam datepicker w mojej aplikacji na Androida, ale teraz chcę zmienić kolor niebieskich dzielników na zielony (patrz obrazek poniżej tego tekstu). Są Niektóre inne dyskusje Na Stackoverflow, które mówią o tym samym, ale żadna z nich nie daje odpowiedzi, która prowadzi do rozwiązania.

Więc poszedłem szukać siebie i znalazłem tam rzeczywiście jest android: datePickerStyle i jest też Android: dzielnik. Nie wiem jednak, czy dzielnik jest rzeczywiście w ogóle odnosi się do dzielnika w datepicker. Próbowałem wielu kombinacji tych dwóch, ale nie wydaje mi się, aby to działało. Więc moje pierwsze pytanie: czy Android: divider odnosi się do dzielnika w datepicker, i jak mogę go użyć do zmiany koloru?

Więc inną opcją jest rzekomo stworzenie całkowicie nowego niestandardowego datepickera. Jeśli to pozwoli mi zmienić kolor dzielnika, jestem na to gotowa. Więc rzuciłem okiem na niektóre z the tutoriale na temat tworzenia niestandardowego datepickera, ale żaden z nich nie wydaje się określać koloru dzielników. Dzielniki nie są po prostu wymienione w plikach xml lub w plikach java.

Byłoby świetnie, gdyby istniał jakiś kod do odtworzenia datepickera, który jest aktualnie wyświetlany, włączając w to kod, który ustawia kolor dzielników. Mam nadzieję, że pozwoli mi to skopiować i po prostu zmienić ustawienie koloru dzielnika gdzieś. Więc mój drugi pytanie: czy ktoś zna jakiś kod boilerplate, który po prostu implementuje datepicker tak, jak jest teraz (w tym definicję dzielników)?

Tutaj wpisz opis obrazka

Author: Community, 2013-11-22

7 answers

Niestety, nie jest to trywialne zadanie.

DatePickers Użyj widżetów NumberPicker i CalendarView wewnętrznie. Na przykład opublikowany obraz używa 3 NumberPickers. A dzielniki, o których mówisz, pochodzą z atrybutu NumberPicker: selectionDivider. Problem polega na tym, że ten atrybut nie jest publiczny, podobnie jak numberPickerStyle, przez który ten atrybut jest ustawiany.

Niedawno przeportowałem CalendarView i NumberPicker do API 8, głównie dla Zabawy. Ponieważ kod jest łatwo dostępny(sprawdź [[9]} i inne w źródle Androida), wszystko to wymaga czasu i trochę przekopania się przez kod źródłowy Androida. Przykłady:

  1. Easy = = > będziesz musiał zmienić prywatną zmienną z klasy View na ich metody dostępu

    MLeft (chroniona zmienna w klasie View) = = > getLeft () (metoda Public accessor)

  2. Najbardziej czasochłonnym zadaniem było przywrócenie metod dostępności.

W każdym razie, jeśli zdecydujesz się na pisząc niestandardową implementację DatePicker, będziesz musiał napisać je również dla NumberPicker i CalendarView (opcjonalnie).

Łatwiejszy sposób:

Backported DatePicker jest dostępny jako biblioteka tutaj: Android-DatePicker . Jak wspomniano powyżej, będziesz używać backported CalendarView i NumberPicker w połączeniu z tym DatePicker.

Co trzeba zmienić:

Użyj {library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.png jako szablonu, oraz Zmień "niebieskawy" kolor na zielony(użyłem pixlr ). Możesz zapisać go o tej samej nazwie, jeśli chcesz zrobić to z Niebieskim dzielnikiem, lub użyć innej nazwy i wprowadzić zmiany w {library-numberpicker} / res / values / themes.xml.

Zmiany wymagane w themes.xml jeśli wybierzesz inną nazwę:

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

I to wszystko.

Wyjście przy użyciu bibliotek:

Tutaj wpisz opis obrazka

Edit:

Czy android:divider odnosi się do dzielnika w datepicker, oraz Jak mogę go użyć do zmiany koloru?

Atrybut divider faktycznie pochodzi od LinearLayout. NumberPicker dziedziczy ten atrybut jako NumberPicker extends LinearLayout. Ale to divider służy innemu celowi. Drawable przekazywane do tego atrybutu jest umieszczane pomiędzy widokami potomnymi LinearLayout.

Atrybut android:showDividers jest używany do zmiany położenia tego dzielnika, możliwe wartości to:

  • none: nie pokazano dzielników
  • początek: dzielnik jest wyświetlany przed pierwszym dzieckiem widok
  • middle: dzielnik jest wyświetlany po każdym widoku potomnym, a nie po ostatnim widoku potomnym
  • koniec: dzielnik jest wyświetlany po ostatnim widoku potomnym

Atrybut {[21] } jest oczywisty.

Mimo że NumberPicker dziedziczy ten atrybut, nie używa go. Jest to widoczne z twoich własnych badań i prób: I tried a multitude of combinations of the two, but I don't seem to get it to work.

Aby zobaczyć atrybut dzielnika w akcji:

<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-owskie obejście przy użyciu Javy odbicie:

Ta odpowiedź tutaj podsunęła mi pomysł. Nie lubię używać refekcji w ogóle, głównie z powodów wymienionych w tej odpowiedzi: Link . Chociaż wymieniam go tutaj ze względu na kompletność, ja sugeruję nie używaj go.

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

Co tu robimy:

  • Extend DatePicker
  • jeśli otworzysz date_picker.xml W sdk/platforms/android-xx/res/layout, zobaczysz, że trzy NumberPickers mają identyfikatory month, day, year. Uzyskujemy dostęp android.internal.R.id, aby uzyskać identyfikatory zasobów dla tych Numberpickerów.
  • tworzymy trzy obiekty NumberPicker używając tych identyfikatorów metodą findViewById(int).
  • następnie uzyskaj dostęp do pola mSelectionDivider za pomocą funkcji relection.
  • Ustaw pole na accessible( jako jego zadeklarowaną ostateczną), ustaw jego wartość za pomocą metody Field#set(Object, Object). Pierwszym argumentem jest obiekt, na którym wykonujemy tę operację. Drugi argument to obiekt, który chcemy ustawić.

Drawable, którego użyłem, można pobrać ze strony: tutaj .

 99
Author: Vikram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:43

Myślę, że najprostszym rozwiązaniem jest prawdopodobnie użycie stylów.

Po prostu włóż to do swojego stylu.dokument 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>

I umieść te atrybuty w układzie XML

android:theme="@style/appCompatStyle"

I dostosować go, jak chcesz.

 19
Author: JCLaHoot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-26 15:39:38

Istnieje jedna biblioteka mają custmize time I date picker. W ten sposób możesz zmienić kolor dzielnika w następujący sposób

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

Edit Inną bibliotekę użyłem również, która jest również dobra, ponieważ można ją dostosować za pomocą następującego sposobu w 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
Author: Rajesh Nasit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-17 03:26:22

Po pierwsze; Vikram, wykonałeś świetną robotę dziękuję za twój wysiłek! Brakowało mi w net.simonvt.datepicker.DatePickerDialog opcji ustawienia koloru titleDivider, który chcę dopasować do numberPickerDividerColor. Dodałem więc tę opcję w implementacji Vikrams i zamieszczam ją tutaj. Jest to powszechne rozwiązanie związane ze zmianą AlertDialog.titleDividerColor. Może to komuś pomoże.

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

Ważne jest, aby ustawić kolor podczas wyświetlania okna dialogowego, więc robię to w metodzie 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

I posted inne rozwiązanie tutaj https://stackoverflow.com/a/33800696/1134335

 0
Author: GMan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:17

Aby zmienić po prostu kolor dzielnika w DatePickerDialog zmiana Androida: styl datePickerDialogTheme w Twoim motywie jest wystarczający:

Styl tematu:

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

Styl dialogowy:

<style name="style_date_picker_dialog" parent="AppCompatAlertDialogStyle">
<item name="colorControlNormal">@color/colorAccent</item>
</style>
 0
Author: Wiktor Wardzichowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-17 13:57:08

Ustawienie motywu na układ DatePicker i dodanie colorControlNormal do niego działa dla mnie.

W XML układu dodaj DatePicker stosowanie motywu, jak pokazano poniżej -

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

A następnie zdefiniuj NumberPickerStyle w styles.xml określając colorControlNormal w ten sposób-

<style name="NumberPickerStyle">
        <item name="colorControlNormal">@color/colorAccent</item>
</style>
 0
Author: shubham1g5,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-07 12:38:38

From wrecker at Android divider color datepicker dialog

Możesz użyć tych atrybutów na przykład:

<NumberPicker
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            selectionDivider="@color/black" //The divider for making the selection area
            selectionDividerHeight="1px"//The height of the selection divider
            selectionDividersDistance="3dp"//The distance between the two selection dividers
            internalLayout="@layout/something"//The layout of the number picker.
            internalMaxHeight="5dp"//The max height of the NumberPicker (also check other variations)
            internalMinWidth="5dp" // The max width of the NumberPicker (also check other variations)
            virtualButtonPressedDrawable="@drawable/something"//The drawable for pressed virtual (increment/decrement) buttons.
            />
 -3
Author: sumit gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:14