Boîte de dialogue de diviseur de couleurs pour Android

j'essaie de changer la couleur des diviseurs bleus pour un curseur de données dans une boîte de dialogue. C'est juste un fragment de dialogue normal avec un curseur de données et une barre de bouton.

est-ce que quelqu'un sait changer ces diviseurs, ou si c'est même possible sans remplacer tout le curseur de données par un personnalisé?

Screenshot DatePicker

Mini coup de gueule

maintenant j'ai vu trop de réponses suggérant le code suivant:

<style name="datePickerTheme" parent="@android:style/Widget.DeviceDefault.DatePicker">
    <item name="android:divider">**your @drawable/ or @color/ here**</item>
</style>

Qui ne fonctionne tout simplement pas. Avez-vous essayé avant de suggérer ce code? devrait fonctionne parfaitement, mais il ne semble pas fonctionner avec le DatePicker.

9
demandé sur Armadillo 2013-09-10 12:46:44

8 réponses

L'approche suivante a fonctionné pour moi.Cela définit les couleurs de séparation pour tous les champs (également pour am/pm)

 private void applyStyLing(TimePickerDialog timePickerDialog){
    Resources system = Resources.getSystem();
    int hourNumberPickerId = system.getIdentifier("hour", "id", "android");
    int minuteNumberPickerId = system.getIdentifier("minute", "id", "android");
    int ampmNumberPickerId = system.getIdentifier("amPm", "id", "android");

    NumberPicker hourNumberPicker = (NumberPicker) timePickerDialog.findViewById(hourNumberPickerId);
    NumberPicker minuteNumberPicker = (NumberPicker) timePickerDialog.findViewById(minuteNumberPickerId);
    NumberPicker ampmNumberPicker = (NumberPicker) timePickerDialog.findViewById(ampmNumberPickerId);

   setNumberPickerDividerColour(hourNumberPicker);
   setNumberPickerDividerColour(minuteNumberPicker);
   setNumberPickerDividerColour(ampmNumberPicker);
}

private void setNumberPickerDividerColour(NumberPicker number_picker){
    final int count = number_picker.getChildCount();

    for(int i = 0; i < count; i++){

        try{
            Field dividerField = number_picker.getClass().getDeclaredField("mSelectionDivider");
            dividerField.setAccessible(true);
                ColorDrawable colorDrawable = new ColorDrawable(mContext.getResources().getColor(R.color
                        .interactive_color));
            dividerField.set(number_picker,colorDrawable);

            number_picker.invalidate();
        }
        catch(NoSuchFieldException e){
            Log.w("setNumberPickerTxtClr", e);
        }
        catch(IllegalAccessException e){
            Log.w("setNumberPickerTxtClr", e);
        }
        catch(IllegalArgumentException e){
            Log.w("setNumberPickerTxtClr", e);
        }
    }
}
17
répondu Ajit 2016-04-26 22:01:16

j'ai résolu ceci en faisant ceci:

j'ai changé le DatePicker diviseur avec réflexion en trouvant le mSelectionDivider ". Puis j'ai eu des problèmes avec le titre divider à l'air stupide, donc j'ai ajouté un textview au-dessus du LinearLayout contenant le 3 datepickers et utilisé newFragment.setTitle(""); pour supprimer l'original.

exemple pour diviseur tirable: crédits au gars qui a fait cela! :) http://ge.tt/8wK7TZ71/v/0?c

image de résultat < - mon résultat

exemple:

    public DatePickerDialog makeDatePicker(OnDateSetListener listener, Calendar cal) {
    Calendar c;
    if (cal == null) {
        c = Calendar.getInstance();
    } else {
        c = cal;
    }
    int year = c.get(Calendar.YEAR);
    int month = c.get(Calendar.MONTH);
    int day = c.get(Calendar.DAY_OF_MONTH);
    DatePickerDialog newFragment = new DatePickerDialog(this, listener, year, month, day);

    // removes the original topbar:
    newFragment.setTitle(""); 

    // Divider changing:
    DatePicker dpView = newFragment.getDatePicker(); 
    LinearLayout llFirst = (LinearLayout) dpView.getChildAt(0);
    LinearLayout llSecond = (LinearLayout) llFirst.getChildAt(0);
    for (int i = 0; i < llSecond.getChildCount(); i++) {
        NumberPicker picker = (NumberPicker) llSecond.getChildAt(i); // Numberpickers in llSecond
        // reflection - picker.setDividerDrawable(divider); << didn't seem to work.
        Field[] pickerFields = NumberPicker.class.getDeclaredFields();
        for (Field pf : pickerFields) {
            if (pf.getName().equals("mSelectionDivider")) {
                pf.setAccessible(true);
                try {
                    pf.set(picker, getResources().getDrawable(R.drawable.np_numberpicker_selection_divider_orange));
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (NotFoundException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }
    // New top:
    int titleHeight = 90;
    // Container:
    LinearLayout llTitleBar = new LinearLayout(this);
    llTitleBar.setOrientation(LinearLayout.VERTICAL);
    llTitleBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, titleHeight));

    // TextView Title:
    TextView tvTitle = new TextView(this);
    tvTitle.setText("Select a date");
    tvTitle.setGravity(Gravity.CENTER);
    tvTitle.setPadding(10, 10, 10, 10);
    tvTitle.setTextSize(24);
    tvTitle.setTextColor(Color.BLACK);
    tvTitle.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, titleHeight-2));
    llTitleBar.addView(tvTitle);

    // View line:
    View vTitleDivider = new View(this);
    vTitleDivider.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 2));
    vTitleDivider.setBackgroundColor(getResources().getColor(R.color.crumblrOrange));
    llTitleBar.addView(vTitleDivider);

    dpView.addView(llTitleBar);
    FrameLayout.LayoutParams lp = (android.widget.FrameLayout.LayoutParams) llFirst.getLayoutParams();
    lp.setMargins(0, titleHeight, 0, 0);
    return newFragment;
}
17
répondu Mvj 2013-12-07 13:03:17

j'ai basé ce code sur réponse D'Ajit , mais je l'ai modifié pour DatePicker plutôt que TimePicker . En outre, j'ai ajouté un null vérifier juste pour rester sur le côté sûr:

public static void colorizeDatePicker(DatePicker datePicker) {
    Resources system = Resources.getSystem();
    int dayId = system.getIdentifier("day", "id", "android");
    int monthId = system.getIdentifier("month", "id", "android");
    int yearId = system.getIdentifier("year", "id", "android");

    NumberPicker dayPicker = (NumberPicker) datePicker.findViewById(dayId);
    NumberPicker monthPicker = (NumberPicker) datePicker.findViewById(monthId);
    NumberPicker yearPicker = (NumberPicker) datePicker.findViewById(yearId);

    setDividerColor(dayPicker);
    setDividerColor(monthPicker);
    setDividerColor(yearPicker);
}

private static void setDividerColor(NumberPicker picker) {
    if (picker == null)
        return;

    final int count = picker.getChildCount();
    for (int i = 0; i < count; i++) {
        try {
            Field dividerField = picker.getClass().getDeclaredField("mSelectionDivider");
            dividerField.setAccessible(true);
            ColorDrawable colorDrawable = new ColorDrawable(picker.getResources().getColor(R.color.colorAccent));
            dividerField.set(picker, colorDrawable);
            picker.invalidate();
        } catch (Exception e) {
            Log.w("setDividerColor", e);
        }
    }
}

Sortie

colored dividers

14
répondu Andrea Lazzarotto 2017-05-23 11:55:07

cela a corrigé mon problème en ajoutant au-dessous de la ligne de code au style du thème de L'application.

<item name="colorControlNormal">@color/colorAccent</item>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/blue</item> 
</style>
5
répondu Jaishree Rathod 2016-11-30 16:39:38

tenir compte:

vous n'avez pas besoin d'un nouveau R.diviseur

vous pouvez écrire:

 pf.set(number_picker, new ColorDrawable(getResources().getColor(R.color.red)));
4
répondu toni 2015-02-18 03:21:42

cette version est ajustée pour une utilisation spécifique avec DatePicker . Alors que la version D'Andrea Lazzarotto fonctionne bien, elle utilise une boucle inutile qui conduit à l'appareil multiple du changement de couleur. En plus des améliorations mineures du code, ma version utilise la couleur primaire du thème app pour correspondre à la couleur du diviseur (voir Comment puis-je obtenir la couleur primaire de mon thème app? ). Testé avec Android 6.0 et 8.0:

private void colorizeDatePicker(final DatePicker datePicker) {
    final Resources system = Resources.getSystem();
    final String defType = "id";
    final String defPackage = "android";

    final int dayId = system.getIdentifier("day", defType, defPackage);
    final int monthId = system.getIdentifier("month", defType, defPackage);
    final int yearId = system.getIdentifier("year", defType, defPackage);

    final NumberPicker dayPicker = (NumberPicker) datePicker.findViewById(dayId);
    final NumberPicker monthPicker = (NumberPicker) datePicker.findViewById(monthId);
    final NumberPicker yearPicker = (NumberPicker) datePicker.findViewById(yearId);

    setDividerColor(dayPicker);
    setDividerColor(monthPicker);
    setDividerColor(yearPicker);
}

private void setDividerColor(final NumberPicker picker) {
    if (picker == null) {
        return;
    }

    try {
        final Field dividerField = picker.getClass().getDeclaredField("mSelectionDivider");
        dividerField.setAccessible(true);

        final TypedValue outValue = new TypedValue();
        getContext().getTheme().resolveAttribute(R.attr.colorPrimary, outValue, true);
        final int dividerColor = outValue.data;

        dividerField.set(picker, new ColorDrawable(dividerColor));
        picker.invalidate();
    } catch (Exception e) {
    }
}
2
répondu Michael Troger 2017-08-01 13:39:32

Oui, bien sûr vous pouvez. Vous pouvez utiliser ces attributs par exemple:

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

mise à jour:

Vous pouvez utiliser ce "151980920 personnalisé" datepicker . C'est hautement personnalisable et compétitif à l'envers. Il utilise essentiellement numberpicker et vous pouvez définir divider en utilisant les attributs ci-dessus.

1
répondu wrecker 2013-09-10 12:43:17

Merci Mvj pour résoudre le problème! J'ai juste pensé que je pourrais aussi montrer mon implémentation de votre solution sur les diviseurs de timepickers.

    TimePickerDialog ptd = new TimePickerDialog(getActivity(), R.style.PickerStyler, this, hour, minute,DateFormat.is24HourFormat(getActivity()));
    ptd.setTitle("");

    //Needs to be try catched
    Field mTimePickerField = ptd.getClass().getDeclaredField("mTimePicker");
    mTimePickerField.setAccessible(true);
    TimePicker mTimePickerInstance = (TimePicker) mTimePickerField.get(ptd);    

    LinearLayout llFirst = (LinearLayout) mTimePickerInstance.getChildAt(0);
    LinearLayout llSecond = (LinearLayout) llFirst.getChildAt(0);
    boolean continiue = false;
    NumberPicker picker = null;
    for (int i = 0; i < llSecond.getChildCount(); i++) {            
        continiue = true;
        try{picker = (NumberPicker) llSecond.getChildAt(i);
            }catch(Exception e){continiue = false;}

        if(continiue){
            Field[] pickerFields = NumberPicker.class.getDeclaredFields();
            for (Field pf : pickerFields) {
                if (pf.getName().equals("mSelectionDivider")) {
                    pf.setAccessible(true);
                    try {
                        pf.set(picker, getResources().getDrawable(R.drawable.divider));
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (NotFoundException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        }
    }   
1
répondu user3532232 2014-05-27 08:02:09