it-swarm-eu.dev

Android: jak změnit barvu děliče datepicker?

Mám v aplikaci pro Android datapicker, ale teď chci změnit barvu modrých přepínačů na zelenou (viz obrázek pod tímto textem). Tam jsou některéjinédiskuse na Stackoverflow, které mluví o stejné, ale žádný z nich neposkytuje odpověď, která by vedla k řešení.

Tak jsem se podíval sám a zjistil, že je vlastně Android: datePickerStyle a tam je také Android: dělič. Nevím však, zda dělič skutečně odkazuje na dělič v datepickeru vůbec. Zkoušel jsem spoustu kombinací obou, ale nezdá se, že by to fungovalo. Takže moje první otázka: Vztahuje se Android: dělič na dělič v datepickeru a jak jsem ho mohl použít ke změně barvy?

Další možností je tedy vytvoření zcela nového uživatelského datapickeru. Pokud mi to dovolí jen změnit barvu děliče, tak jsem na to. Tak jsem se podíval na některéztutoriálů na vytvoření vlastního nástroje pro tvorbu datapickeru, ale žádný z nich zřejmě nedefinoval barvu rozdělovače. Rozdělovače nejsou jednoduše uvedeny v souborech xml nebo v souborech Java.

Bylo by skvělé, kdyby existoval nějaký kód varné desky, který by znovu vytvořil datapicker tak, jak je aktuálně zobrazen, včetně kódu, který nastavuje barvu děliček. Doufejme, že by mi to umožnilo zkopírovat a někde změnit nastavení barev děliče. Takže moje druhá otázka: Byl by někdo znát jakýkoliv kód kotle, který by jednoduše implementoval datepickera, jak je tomu nyní (včetně definice děliček)?

enter image description here

35
kramer65

Bohužel to není triviální úkol.

DatePickers interně používají widgety NumberPicker a CalendarView. Například obrázek, který jste odeslali, používá 3 NumberPickers. A rozdělovače, o kterých mluvíte, pocházejí z atributu NumberPicker: selectionDivider. Problém je v tom, že tento atribut není veřejný a ani numberPickerStyle, kterým je tento atribut nastaven. 

Nedávno jsem back-portoval CalendarView a NumberPicker na API 8, většinou pro zábavu. Vzhledem k tomu, že kód je snadno dostupný (podívejte se na Android.widget.NumberPicker a další ve zdroji Androidu), je tento úkol časově náročný a některé kopy procházejí zdrojovým kódem Androidu. Příklady:

  1. Easy ==> Budete muset změnit soukromou proměnnou z třídy View na jejich přístupové metody

    mLeft (chráněná proměnná ve třídě View) ==> getLeft () (metoda veřejného přístupu)

  2. Nejvíce časově náročným úkolem bylo obnovení přístupových metod.

V každém případě, pokud se rozhodnete psát vlastní implementaci aplikace DatePicker, musíte je také napsat pro NumberPicker a CalendarView (volitelně).

Snadnější způsob:

Backported DatePicker je k dispozici jako knihovna zde: Android-DatePicker . Jak bylo uvedeno výše, budete používat backported CalendarView a NumberPicker ve spojení s tímto DatePicker.

Co potřebujete změnit:

Použijte {library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.png jako šablonu a změňte modravou barvu na zelenou (používal jsem pixlr ). Můžete jej uložit buď se stejným názvem, pokud chcete být provedeny s modrým děličem úplně, nebo použít jiné jméno a provést změny v {library-numberpicker} / res / values / themes.xml

Změny požadované v souboru themes.xml, pokud zvolíte jiné jméno:

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

A to je vše.

Výstup pomocí knihoven:

enter image description here

Upravit:

Vztahuje se Android:divider na dělič v datepickeru a Jak jsem ho mohl použít ke změně barvy?

Atribut divider pochází vlastně z LinearLayout. NumberPicker dědí tento atribut jako NumberPicker extends LinearLayout. Toto divider však slouží jinému účelu. Kresba předaná tomuto atributu je umístěna mezi podřízené pohledy LinearLayout

Atribut Android:showDividers se používá ke změně umístění tohoto děliče, možné hodnoty jsou:

  • žádné: Zobrazeny nejsou žádné oddělovače
  • začátek: Oddělovač je zobrazen před prvním dítětem
  • uprostřed: Oddělovač se zobrazuje po každém zobrazení dítěte, nikoli po posledním zobrazení dítěte
  • konec: Za posledním dítětem se zobrazí Oddělovač

Atribut Android:dividerPadding je samozřejmý.

Přestože NumberPicker dědí tento atribut, nepoužívá jej. To je zřejmé z vlastního výzkumu a pokusů: I tried a multitude of combinations of the two, but I don't seem to get it to work.

Zobrazení atributu děliče v akci:

<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 řešení pomocí reflexe jazyka Java:

Tato odpověď zde mi dala nápad. Nenávidím používání refekce obecně, většinou z důvodů uvedených v této odpovědi: Link . I když zde uvádím úplnost, I navrhuji, nepoužíváte ho.

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 děláme zde:

  • Rozšiřte položku DatePicker
  • Pokud otevřete date_picker.xml v sdk/platforms/Android-xx/res/layout, uvidíte, že tři NumberPickers mají idmonth, day, year. Přístup Android.internal.R.id zpřístupníme ID zdrojů pro tyto NumberPickers.
  • Pomocí těchto id s metodou findViewById(int) vytváríme tři objekty NumberPicker.
  • Poté přistupujte k poli mSelectionDivider pomocí pole relection.
  • Nastavte pole na přístupné (jako jeho deklarované konečné), nastavte jeho hodnotu pomocí Field#set(Object, Object) metody. Prvním argumentem je objekt, ve kterém tuto operaci provádíme. Druhým argumentem je objekt, který chceme nastavit.

Tahatel, který jsem použil, si můžete stáhnout z: zde .

100
Vikram

Myslím, že nejjednodušším řešením je pravděpodobně použití stylů.

Dejte to do svého styles.xml dokumentu

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

a umístit tyto atributy do XML rozvržení

Android:theme="@style/appCompatStyle"

a přizpůsobte si ho, jak chcete.

22
JCLaHoot

Existuje jedna knihovna mají custmize čas a datum výběr. V tom můžete změnit barvu děliče následujícím způsobem

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

Edit Další knihovna Také jsem použil, že je také dobrý v tom, že si můžete přizpůsobit pomocí následující cesty v.

<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

Nastavení motivu na DatePicker rozvržení a přidání colorControlNormal do něj funguje.

V xml rozvržení přidejte DatePicker použití motivu, jak je uvedeno níže - 

<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 pak definujte NumberPickerStyle v styles.xml určující colorControlNormal jako je tato -

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

Nejdříve; Vikram, dělal jsi skvělou práci, děkuji za vaši snahu! Jedna věc, kterou jsem chyběla v net.simonvt.datepicker.DatePickerDialog byla možnost nastavit titleDivider barvu, kterou chci shodovat s numberPickerDividerColor. Tak jsem přidal tuto možnost v implementaci Vikrams a jsem to zveřejnění zde. Je to běžné řešení týkající se změny AlertDialog.titleDividerColor. Možná to někomu pomůže.

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

Je důležité nastavit barvu, když se zobrazí dialog, takže to dělám v onAttachedToWindow metodě.

@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;
}

UPRAVIT

Napsal jsem další řešení zde https://stackoverflow.com/a/33800696/1134335

0
GMan

Pro změnu pouze dělící barvy v DatePickerDialog mění Android: datePickerDialogTheme styl ve vašem motivu je dostačující: 

Styl motivu:

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

Styl dialogu:

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