Подтвердить что ты не робот

Android: как изменить цвет разделителя datepicker?

У меня есть приложение datepicker в Android-приложении, но теперь я хочу изменить цвет синих разделителей на зеленый (см. изображение ниже этого текста). Есть некоторые другие обсуждения в Stackoverflow, которые говорить об одном и том же, но ни один из них не дает ответа, который приводит к решению.

Итак, я пошел искать себя и нашел, что на самом деле есть андроид: datePickerStyle, и есть также android: divider. Однако я не знаю, действительно ли делитель на самом деле ссылается на разделитель в datepicker. Я попробовал множество комбинаций из двух, но мне кажется, что это не работает. Итак, мой первый вопрос: Разделяет ли android: divider разделитель в datepicker и как я могу использовать его для изменения цвета?

Так что еще один вариант - создать совершенно новый пользовательский дампикер. Если это позволяет мне просто изменить цвет разделителя, я за него. Поэтому я посмотрел на несколько учебные пособия о создании пользовательского дампикера, но ни один из них как представляется, определяют цвет разделителей. Разделители просто не указаны в файлах xml или в java файлах.

Было бы здорово, если бы был какой-то шаблонный код для воссоздания datepicker по мере его отображения, включая код, который устанавливает цвет разделителей. Надеюсь, это позволит мне скопировать его и просто изменить настройку цвета разделителя где-нибудь. Итак, мой второй вопрос: Кто-нибудь знает какой-либо шаблонный код, который просто реализует датупик, как сейчас (включая определение разделителей)?

enter image description here

4b9b3361

Ответ 1

К сожалению, это не тривиальная задача.

DatePickers использовать виджеты NumberPicker и CalendarView внутренне. Например, изображение, которое вы опубликовали, использует 3 NumberPickers. И разделители, о которых вы говорите, исходят из атрибута NumberPicker: selectionDivider. Проблема в том, что этот атрибут не является общедоступным, и ни один numberPickerStyle, через который этот атрибут не установлен.

Недавно я обновил CalendarView и NumberPicker до API 8, в основном для развлечения. Так как код легко доступен (посмотрите android.widget.NumberPicker и другие в источнике android), все это задача занимает время, а некоторые копаются через исходный код Android. Примеры:

  • Easy == > Вам придется изменить приватную переменную из класса View в их методы доступа

    mLeft (защищенная переменная в классе View) == > getLeft() (общедоступный метод доступа)

  • Самая трудоемкая задача - восстановить методы доступности.

В любом случае, если вы решите написать пользовательскую реализацию DatePicker, вам придется писать их для NumberPicker и CalendarView (необязательно).

Простой способ:

Backported DatePicker доступен в виде библиотеки здесь: Android-DatePicker. Как упоминалось выше, вы будете использовать backported CalendarView и NumberPicker в сочетании с этим DatePicker.

Что вам нужно изменить:

Используйте {library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.png в качестве шаблона и измените "голубоватый" цвет на зеленый (я использовал pixlr). Вы можете сохранить его с тем же именем, если хотите сделать это с помощью синего разделителя вообще или использовать другое имя и внести изменения в {library-numberpicker} / res / values / themes.xml.

Изменения, требуемые в themes.xml, если вы выберете другое имя:

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

И что это.

Вывод с использованием библиотек:

enter image description here

Edit:

Относится ли android:divider к делителю в datepicker и как я могу использовать его для изменения цвета?

Атрибут divider на самом деле происходит от LinearLayout. NumberPicker наследует этот атрибут как NumberPicker extends LinearLayout. Но это divider служит другой цели. Выделение, переданное этому атрибуту, помещается между дочерними представлениями LinearLayout.

Атрибут android:showDividers используется для изменения размещения этого разделителя, возможны следующие значения:

  • нет: нет показанных разделителей
  • начало: разделитель отображается перед представлением первого ребенка
  • middle: Divider отображается после каждого дочернего представления, а не после последнего детского представления
  • end: Divider отображается после последнего детского представления

Атрибут android:dividerPadding не требует пояснений.

Несмотря на то, что NumberPicker наследует этот атрибут, он не использует его. Это видно из ваших собственных исследований и испытаний: I tried a multitude of combinations of the two, but I don't seem to get it to work.

Чтобы увидеть атрибут divider в действии:

<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 с использованием java-отражения:

Этот ответ здесь дал мне эту идею. Я ненавижу использование рефлексов вообще, в основном по причинам, перечисленным в этом ответе: Ссылка. Хотя я перечисляю его здесь для полноты, я предлагаю вам не использовать его.

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

Что мы здесь делаем:

  • Расширить DatePicker
  • Если вы откроете date_picker.xml в sdk/platforms/android-xx/res/layout, вы увидите, что у трех NumberPickers есть идентификаторы month, day, year. Мы получаем доступ к android.internal.R.id, чтобы получить идентификаторы ресурсов для этих NumberPickers.
  • Мы создаем три объекта NumberPicker, используя эти идентификаторы с помощью метода findViewById(int).
  • Затем выберите и извлеките поле mSelectionDivider, используя выбор.
  • Установите доступное поле (как его объявленное окончание), установите его значение с помощью метода Field#set(Object, Object). Первый аргумент - это объект, над которым мы выполняем эту операцию. Второй аргумент - это Object, который мы хотим установить.

Загружаемый множитель можно скачать с помощью здесь.

Ответ 2

Я думаю, что наиболее простым решением, вероятно, является использование стилей.

Просто поместите это в свой документ styles.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>

и поместите эти атрибуты в свой макет XML

android:theme="@style/appCompatStyle"

и настройте его, как вам нравится.

Ответ 3

Существует одна библиотека, они имеют время и время для выбора времени. В этом вы можете изменить цвет разделителя следующим образом

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

Edit Еще одна библиотека Я также использовал это, также хорошо, что вы можете настроить, используя следующий способ в 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>

Ответ 4

Прежде всего; Викрам, ты отлично поработал благодаря своим усилиям! Одна вещь, которую я отсутствовал в net.simonvt.datepicker.DatePickerDialog, - это возможность установить цвет titleDivider, который я хочу сопоставить с numberPickerDividerColor. Поэтому я добавил эту опцию в реализацию Vikrams и размещаю ее здесь. Это общее решение, связанное с изменением AlertDialog.titleDividerColor. Может быть, это поможет кому-то.

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

Важно установить цвет при отображении диалога, поэтому я делаю это в методе 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;
}

ИЗМЕНИТЬ

Я разместил здесь другое решение fooobar.com/questions/58809/...

Ответ 5

Для изменения цвета только разделителя в диалоговом окне изменения даты DatePickerDialog: datePickerDialogTheme в вашей теме достаточно:

Стиль темы:

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

Стиль диалога:

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

Ответ 6

От wrecker в Диалоговое окно DatePicker цветной панели Android

Вы можете использовать эти атрибуты, например:

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