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)?
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:
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)
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:
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:
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:
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.findViewById(int)
vytváríme tři objekty NumberPicker.mSelectionDivider
pomocí pole relection.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 .
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.
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>
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>
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
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>