web-dev-qa-db-fra.com

Android: comment changer la couleur du séparateur de datepicker?

J'ai un datepicker dans mon application Android, mais je souhaite maintenant changer la couleur des diviseurs bleus en vert (voir l'image ci-dessous ce texte). Il y a certains _ { autres _ { discussions sur Stackoverflow qui parlent de la même chose, mais aucun d'eux ne donne une réponse qui mène à une solution.

Alors je suis allé me ​​chercher et j'ai trouvé qu'il y avait un Android: datePickerStyle et aussi un Android: diviseur. Cependant, je ne sais pas si le diviseur se réfère réellement au diviseur dans le sélecteur de date. J'ai essayé une multitude de combinaisons des deux, mais je ne semble pas le faire fonctionner. Alors ma première question: Est-ce que le diviseur Android: fait référence au diviseur dans le sélecteur de date, et comment puis-je l’utiliser pour changer de couleur?

Donc, une autre option est censée créer un tout nouveau sélecteur de date personnalisé. Si cela me permet de changer simplement la couleur du séparateur, je suis pour cela. Alors j’ai jeté un œil à certains _ { de _ { letutoriels sur la création d’un sélecteur de date personnalisé, mais aucun d’entre eux ne semble définir la couleur de les diviseurs. Les diviseurs ne sont tout simplement pas répertoriés dans les fichiers XML ni dans les fichiers Java.

Ce serait génial s'il existait une sorte de code standard pour recréer le sélecteur de date tel qu'il s'affiche actuellement, y compris le code qui définit la couleur des séparateurs. J'espère que cela me permettrait de le copier et de changer simplement le réglage de la couleur du séparateur quelque part. Donc ma deuxième question: Est-ce que quelqu'un connaît un code standard qui implémente simplement le sélecteur de date tel qu'il est actuellement (avec une définition des diviseurs)?

enter image description here

35
kramer65

Malheureusement, ce n'est pas une tâche triviale.

DatePickers utilise les widgets NumberPicker et CalendarView en interne. Par exemple, l’image que vous avez publiée utilise 3 NumberPickers. Et les séparateurs dont vous parlez proviennent de l'attribut de NumberPicker: selectionDivider. Le problème est que cet attribut n'est pas public, et numberPickerStyle non plus, par lequel cet attribut est défini. 

J'ai récemment rétabli CalendarView et NumberPicker sur API 8, principalement pour le plaisir. Étant donné que le code est facilement disponible (recherchez Android.widget.NumberPicker et les autres dans le code source d'Android), toute cette tâche prend du temps, et certains creusent dans le code source d'Android. Exemples:

  1. Facile ==> Vous devrez changer la variable privée de la classe View en méthodes d'accès.

    mLeft (variable protégée dans la classe View) ==> getLeft () (méthode d'accès public)

  2. La tâche qui a pris le plus de temps a été la restauration des méthodes d'accessibilité.

Dans tous les cas, si vous décidez d'écrire une implémentation personnalisée de DatePicker, vous devrez également les écrire pour NumberPicker et CalendarView (éventuellement).

Manière plus simple:

Backported DatePicker est disponible sous forme de bibliothèque ici: Android-DatePicker . Comme mentionné ci-dessus, vous utiliserez backported CalendarView et NumberPicker en conjonction avec ce DatePicker.

Ce que vous devez changer:

Utilisez {library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.png comme modèle et changez la couleur «bleuâtre» en vert (j'ai utilisé pixlr ). Vous pouvez soit l'enregistrer sous le même nom, si vous souhaitez utiliser le séparateur bleu, soit utiliser un nom différent et apporter des modifications dans {library-numberpicker} / res / values / themes.xml

Les modifications requises dans themes.xml si vous choisissez un nom différent:

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

Et c'est tout.

Sortie utilisant les bibliothèques:

enter image description here

Modifier:

Est-ce que le Android:divider fait référence au diviseur dans le sélecteur de date et à comment pourrais-je l'utiliser pour changer de couleur?

L'attribut divider provient en réalité de LinearLayout. NumberPicker hérite de cet attribut en tant que NumberPicker extends LinearLayout. Mais cette divider a un but différent. Le tirage transmis à cet attribut est placé entre les vues enfant de LinearLayout

L'attribut Android:showDividers permet de modifier l'emplacement de ce séparateur, les valeurs possibles étant:

  • aucun: aucun séparateur montré
  • début: le séparateur est affiché avant la première vue enfant
  • middle: un séparateur est affiché après chaque vue enfant, pas après la dernière vue enfant
  • end: le séparateur est affiché après la dernière vue enfant

L'attribut Android:dividerPadding est explicite.

Même si NumberPicker hérite de cet attribut, il ne l'utilise pas. Cela ressort clairement de vos propres recherches et essais: I tried a multitude of combinations of the two, but I don't seem to get it to work.

Pour voir l'attribut diviseur en action:

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

Solution de contournement Hack-ish utilisant la réflexion Java:

Cette réponse ici m'a donné l'idée. Je déteste utiliser la réflexion en général, principalement pour les raisons énumérées dans cette réponse: Link . Bien que je l'énumère ici par souci d'exhaustivité, je suggère que vous ne l'utilisiez pas.

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

Ce que nous faisons ici:

  • Prolonger DatePicker
  • Si vous ouvrez date_picker.xml dans sdk/platforms/Android-xx/res/layout, vous constaterez que les trois NumberPickers ont des ids month, day, year. Nous accédons à Android.internal.R.id pour obtenir les identifiants de ressources de ces NumberPickers.
  • Nous créons trois objets NumberPicker en utilisant ces identifiants avec la méthode findViewById(int).
  • Ensuite, accédez au champ mSelectionDivider et récupérez-le à l’aide de la relection.
  • Définissez le champ sur accessible (en tant que finale déclarée), définissez sa valeur à l'aide de la méthode Field#set(Object, Object). Le premier argument est l'objet sur lequel nous effectuons cette opération. Le deuxième argument est l’objet que nous voulons définir.

Le dessin que j'ai utilisé peut être téléchargé à partir de: ici .

100
Vikram

Je pense que la solution la plus simple est probablement d'utiliser des styles.

Il suffit de mettre cela dans votre document 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>

et mettre ces attributs dans votre mise en page XML

Android:theme="@style/appCompatStyle"

et le personnaliser comme vous le souhaitez.

22
JCLaHoot

Il y a un bibliothèque ils ont un sélecteur d'heure et de date personnalisé. En ce que vous pouvez changer la couleur du séparateur de la manière suivante

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

Edit Un autre bibliothèque j’ai aussi utilisé, qui est également bon car vous pouvez le personnaliser de la manière suivante dans 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
Rajesh Nasit

Définir un thème sur la disposition DatePicker et y ajouter colorControlNormal me convient.

Dans le code XML de votre mise en page, ajoutez une DatePicker en appliquant un thème, comme indiqué ci-dessous - 

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

puis définissez la NumberPickerStyle dans styles.xml en spécifiant colorControlNormal comme ceci -

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

Tout d'abord; Vikram, tu as fait un excellent travail, merci pour tes efforts! Une chose qui me manquait dans net.simonvt.datepicker.DatePickerDialog était l'option permettant de définir la couleur titleDivider que je veux faire correspondre à numberPickerDividerColor. J'ai donc ajouté cette option dans la mise en œuvre de Vikrams et la publie ici. C'est une solution courante liée à la modification de AlertDialog.titleDividerColor. Cela aidera peut-être quelqu'un.

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

Il est important de définir la couleur lorsque la boîte de dialogue est affichée. Je le fais donc avec la méthode 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;
}

MODIFIER

J'ai posté une autre solution ici https://stackoverflow.com/a/33800696/1134335

0
GMan

Pour changer la couleur du séparateur dans DatePickerDialog, le changement d'Android: le style datePickerDialogTheme dans votre thème est suffisant: 

Style de thème:

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

Style de dialogue:

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