web-dev-qa-db-fra.com

DatePicker.OnDateChangedListener appelé deux fois

J'essaie de créer une application dans laquelle l'utilisateur sélectionne une date dans un DatePicker, puis une liste est mise à jour avec quelques valeurs.

Mon interface graphique ressemble à ceci:

    <LinearLayout
    Android:id="@+id/linearLayout1"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_gravity="center" >


    <DatePicker
        Android:id="@+id/datePicker"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content" />

</LinearLayout>

<LinearLayout
    Android:id="@+id/linearLayout2"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content" >



   <ListView
        Android:id="@+id/list"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_weight="1" >


    </ListView> 
</LinearLayout>

Alors que l'initialisation et la gestion de DatePicker se présentent comme suit:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    datePicker = (DatePicker) findViewById(R.id.datePicker);

    Calendar c = Calendar.getInstance();

    year = c.get(Calendar.YEAR);
    month = c.get(Calendar.MONTH);
    day = c.get(Calendar.DAY_OF_MONTH);

    datePicker.init(year, month, day, dateSetListener);
}

private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() {

    public void onDateChanged(DatePicker view, int year, int monthOfYear,
            int dayOfMonth) {
         Calendar c = Calendar.getInstance();
         c.set(year, monthOfYear, dayOfMonth);
         System.out.println ("TEST");

    }
};

Dans CatLog, je vois que la chaîne "TEST" est émise deux fois, chaque fois que je joue avec les boutons +/- du widget. Quel pourrait être le problème?

Remarque: j'ai "désactivé" le code de mise à jour de la liste à dessein, afin de vous assurer que le problème n'est pas lié à ListView, comme dans ici

48
tomor

Lorsque je teste mon application, la méthode onDateSet est appelée deux fois après avoir accepté la sélection de la date et une fois lorsque j'ai annulé.

J'ai ajouté une validation dans la méthode onDateSet avec la vue des paramètres, quelque chose comme ça

@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth){
    if (view.isShown()) {
        updateDate(year, monthOfYear, dayOfMonth);
    }
}

J'espère que vous servez

139
Cesardl

Je n'ai toujours pas réussi à trouver un correctif. J'ai plutôt trouvé une solution de contournement, donc l'événement ne se déclenche pas deux fois. La solution de contournement est la suivante:

int timesCalled = 1;

private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() {

public void onDateChanged(DatePicker view, int year, int monthOfYear,
        int dayOfMonth) {
     Calendar c = Calendar.getInstance();
     c.set(year, monthOfYear, dayOfMonth);
     timesCalled += 1;

     if ((timesCalled % 2) == 0) {
        System.out.println ("TEST");
     }

}};
9
tomor

Au lieu du rappel onDateSet, j'ai remplacé la méthode onClick de la boîte de dialogue DatePickerDialog et ne gère que les clics BUTTON_POSITIVE.

public static class DatePickerFragment extends DialogFragment {
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final Calendar c = Calendar.getInstance();
        int initialYear = c.get(Calendar.YEAR);
        int initialMonth = c.get(Calendar.MONTH);
        int initialDay = c.get(Calendar.DAY_OF_MONTH);
        return new DatePickerDialog(getActivity(), null, initialYear, initialMonth, initialDay) {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (which == BUTTON_POSITIVE) {
                    int year = getDatePicker().getYear();
                    int month = getDatePicker().getMonth();
                    int day = getDatePicker().getDayOfMonth();

                    //TODO: Do your logic here
                }
                super.onClick(dialog, which);
            }
        };
    }
}

Le code reste clair mais on ne sait toujours pas pourquoi onDateSet est appelé deux fois.

2

Modifiez peut-être l'écouteur en ajoutant des variables d'instance, de cette façon, vous pouvez vérifier si elles sont différentes de la dernière fois que la méthode a été appelée:

final DatePickerDialog datePickerDialog = new DatePickerDialog (this, new DatePickerDialog.OnDateSetListener()
    {   
        private int year;
        private int month;
        private int day;

        @Override
        public void onDateSet (DatePicker view, int year, int monthOfYear, int dayOfMonth)
        {
            if (this.year == year && this.month == monthOfYear && this.day == dayOfMonth)
                return;

            this.year = year;
            this.month = monthOfYear;
            this.day = dayOfMonth;

            calendar.set (year, month, day);
            int index = officeCalendar.indexOfKey (calendar.getTimeInMillis ());

            if (index > -1)
                viewPager.setCurrentItem (index);
        }
    }, calendar.get (Calendar.YEAR), calendar.get (Calendar.MONTH), calendar.get (Calendar.DATE));
0
Graeme
private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() {
    boolean fired = false;
    public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
         if (fired == true){
//Twince
         }
         else{
             Calendar c = Calendar.getInstance();
             c.set(year, monthOfYear, dayOfMonth);
             System.out.println ("TEST");
         }

    }
};
0

Veuillez vérifier ma réponse ici. C'est pour TimePickerDialog mais également applicable pour DatePickerDialog. Vous pouvez créer une boîte de dialogue personnalisée, elle est presque aussi rapide et simple et fonctionne simplement.

https://stackoverflow.com/a/25672760/94045

0
iamronak
private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() { 

    public void onDateChanged(DatePicker view, int year, int monthOfYear, 
            int dayOfMonth) { 
         Calendar c = Calendar.getInstance(); 
         c.set(year, monthOfYear, dayOfMonth); 
         updateDisplay();

    } 
}; 


TextView datetext;
datetext = (TextView) findViewById(R.id.selected_date);


private void updateDisplay() {
        this.datetext.setText(new StringBuilder()
                // Month is 0 based so add 1
                .append(mMonth + 1).append("-").append(mDay).append("-")
                .append(mYear).append(" "));
    }
0
user1640247

Pas nécessaire d'ajouter ce code sous Jelly beans

@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth){
    if (view.isShown()) {
        updateDate(year, monthOfYear, dayOfMonth);
    }
}
0
user3922209