19 votes

Android : Émulateur Android 4.1 invoquant onDateSet deux fois à partir d'une boîte de dialogue DatePicker

Mon application fonctionnait parfaitement sur mon émulateur Android 2.2. J'ai ensuite décidé de la tester sur un émulateur Android 4.1. Le site DatePickerDialog a l'air un peu différent et, pour une raison quelconque, lorsque j'appuie sur "Done", la onDateSet() est appelé deux fois et cause des problèmes dans mon application.

Je le sais parce que le journal indiqué ci-dessous dans le code est imprimé deux fois chaque fois que je clique sur "Done".

mDateSetListener = new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            Log.v("onDateSet", "ENTERED");
            //rest of code...
    }};

Android 2.2 DatePicker

Working Android 2.2 DatePicker

Android 4.1 DatePicker

Not Working Android 4.1 DatePicker

25voto

lodlock Points 517

Essayez de définir un booléen pour vérifier s'il y a un double feu dans le même dialogue. Quelque chose de similaire à :

Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_YEAR, 1);
final DatePickerDialog dateDialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
    boolean fired = false;
    public void onDateSet(final DatePicker view, final int year, final int monthOfYear, final int dayOfMonth) {
        Log.i("PEW PEW", "Double fire check");
        if (fired) {
            Log.i("PEW PEW", "Double fire occured. Silently-ish returning");
            return;
        } else {
            //first time fired
            fired = true;
        }
        //Normal date picking logic goes here
    }
}, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
dateDialog.show();

Ce problème de double déclenchement se produit également avec onTimeSet d'un TimePickerDialog et cette vérification fonctionne également pour ceux-ci.

1voto

AbdelHady Points 576

Selon le brillant ouvrage d'Ankur Chaudhary. réponse sur le même TimePickerDialog si nous vérifions à l'intérieur de onDateSet si la vue donnée isShown() ou non, cela résoudra tout le problème avec un minimum d'effort, sans qu'il soit nécessaire d'étendre le sélecteur ou de vérifier la présence de drapeaux hideux dans le code ou même de vérifier la version du système d'exploitation, il suffit de faire ce qui suit :

public void onDateSet(DatePicker view, int year, int month, int day) {
    if (view.isShown()) {
        // read the date here :)
    }
}

et bien sûr, la même chose peut être faite pour onTimeSet selon la réponse d'Ankur

0voto

Dan Points 81

Je pense que c'est lié, j'ai commencé à tester la 4.1 aujourd'hui et j'ai constaté que certains événements javascript semblent se déclencher deux fois. Pour l'instant, il s'agit surtout de clics. Bizarrement, si j'ajoute une alerte, elle se déclenche " parfois " une fois. Le comportement est étrangement incohérent.

Les événements javascript ne réagissent de cette manière que sur Android 4.1. L'iPhone semble fonctionner correctement, de même que toutes les versions précédentes d'Android que j'ai essayées jusqu'à présent (y compris 4.0.x).

Cela ressemble à une erreur du navigateur ou de la façon dont il gère le javascript, mais ce n'est qu'une supposition.

0voto

leondepeon Points 1912

Pour réitérer : C'est un bug confirmé dans Android. Deux solutions de contournement ont déjà été suggérées : sauvegarder l'état dans une variable (d'instance) ou demander au dialogue s'il est en cours de traitement. isShown() . Mais isShown() semble être peu fiable (selon les commentaires de cette réponse par exemple) et la sauvegarde de l'état devient compliquée si vous voulez réafficher la boîte de dialogue.
Une meilleure solution consiste à enregistrer l'état dans la boîte de dialogue elle-même :

public void onDateSet(DatePicker picker, int year, int monthOfYear, int dayOfMonth) {
    if (picker.getTag() == null) {
        picker.setTag("TAGGED");
        // Only gets called once per Dialog
    }
}

C'est propre et efficace.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X