J'essaie d'empêcher l'activité de se charger deux fois si j'appuie deux fois sur le bouton immédiatement après le premier clic.
J'ai une activité qui se charge en cliquant sur un bouton, par exemple
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//Load another activity
}
});
Maintenant que l'activité à charger a des appels réseau, le chargement prend un peu de temps (MVC). Je montre une vue de chargement pour cela, mais si j'appuie deux fois sur le bouton avant cela, je peux voir l'activité chargée deux fois.
Est-ce que quelqu'un sait comment éviter cela?
Réponses:
Dans l'écouteur d'événements du bouton, désactivez le bouton et affichez une autre activité.
Remplacer
onResume()
pour réactiver le bouton.la source
Ajoutez ceci à votre
Activity
définition dansAndroidManifest.xml
...Par exemple:
la source
android:launchMode = "singleTop"
, qui réalise l'effet sans briser le multitâche Android. La documentation indique que la plupart des applications ne doivent pas utiliser l'singleInstance
option.Vous pouvez utiliser les indicateurs d'intention comme ceci.
Une seule activité sera ouverte en haut de la pile d'historique.
la source
android:launchMode = "singleTop"
cette façon, il est résolu sans avoir à ajouter l'indicateur à chaque intention.Puisque SO ne me permet pas de commenter d'autres réponses, je dois polluer ce fil avec une nouvelle réponse.
Réponses courantes au problème "L'activité s'ouvre deux fois" et mes expériences avec ces solutions (Android 7.1.1):
EDIT: C'était pour démarrer des activités avec startActivity (). Lors de l'utilisation de startActivityForResult (), je dois définir à la fois FLAG_ACTIVITY_SINGLE_TOP et FLAG_ACTIVITY_CLEAR_TOP.
la source
Cela ne fonctionnait que pour moi quand
startActivity(intent)
la source
android:launchMode = "singleInstance"
dans le fichier Manifest de votre tag d'activité?Utilisez singleInstance pour éviter toute activité à invoquer deux fois.
la source
Disons que @wannik a raison, mais si nous avons plus d'un bouton appelant le même auditeur d'action et que je clique sur deux boutons une fois presque en même temps avant de commencer l'activité suivante ...
Donc c'est bien si vous avez le champ
private boolean mIsClicked = false;
et dans l'auditeur:Et
onResume()
nous devons retourner l'état:Quelle est la différence entre ma réponse et celle de @ wannik?
Si vous définissez enabled sur false dans l'écouteur de son appel, voir l'autre bouton utilisant le même auditeur sera toujours activé. Donc, pour être sûr que l'action de l'auditeur n'est pas appelée deux fois, vous devez avoir quelque chose de global qui désactive tous les appels de l'auditeur (peu importe s'il s'agit d'une nouvelle instance ou non)
Quelle est la différence entre ma réponse et les autres?
Ils pensent de la bonne manière mais ils ne pensent pas à un retour futur à la même instance de l'activité d'appel :)
la source
synchronized(mIsClicked) {...}
pour être sûr à 100%.Pour cette situation, je vais opter pour l'un des deux approchés,
singleTask
dans manifest.xml OU un drapeau dans leonResume()
&onDestroy()
méthodes méthodes respectivement.Pour la première solution: je préfère utiliser
singleTask
pour l'activité dans le manifeste plutôt quesingleInstance
, selon l'utilisation,singleInstance
j'ai compris que dans certaines occasions, l'activité créant une nouvelle instance distincte pour elle-même, ce qui entraîne une fenêtre d'applications distinctes dans les applications en cours d'exécution dans bcakground et en plus des allocations de mémoire supplémentaires qui entraîneraient une très mauvaise expérience utilisateur lorsque l'utilisateur ouvre la vue des applications pour choisir une application à reprendre. Donc, le meilleur moyen est d'avoir l'activité définie dans le manifest.xml comme suit:vous pouvez vérifier les modes de lancement d'activité ici .
Pour la deuxième solution, il suffit de définir une variable statique ou une variable de préférence, par exemple:
et de l'autre côté lorsque vous souhaitez lancer cette activité, il suffit de cocher:
la source
Je pense que vous allez résoudre le problème de la mauvaise façon. En général , il est une mauvaise idée pour une activité à faire des demandes Web de longue date dans l' une de ses méthodes de cycle de vie de démarrage (
onCreate()
,onResume()
, etc.). En réalité, ces méthodes devraient simplement être utilisées pour instancier et initialiser les objets que votre activité utilisera et devraient donc être relativement rapides.Si vous devez effectuer une requête Web, faites-le dans un fil d'arrière-plan de votre activité nouvellement lancée (et affichez la boîte de dialogue de chargement dans la nouvelle activité). Une fois le thread de demande d'arrière-plan terminé, il peut mettre à jour l'activité et masquer la boîte de dialogue.
Cela signifie alors que votre nouvelle activité doit être lancée immédiatement et empêcher le double clic d'être possible.
la source
J'espère que cela t'aides:
la source
Une autre solution très très simple si vous ne voulez pas l'utiliser
onActivityResult()
est de désactiver le bouton pendant 2 secondes (ou le temps que vous voulez), ce n'est pas idéal, mais peut résoudre en partie le problème dans certains cas et le code est simple:la source
// variable pour suivre l'heure de l'événement
2.Dans onClick, vérifiez que si l'heure actuelle et le décalage horaire du dernier clic sont inférieurs à i seconde, ne faites rien (retour) sinon allez pour l'événement de clic
la source
Maintenez simplement un indicateur dans la méthode Button onClick comme:
public booléen oneTimeLoadActivity = false;
la source
Si vous utilisez onActivityResult, vous pouvez utiliser une variable pour enregistrer l'état.
Fonctionne sur le bouton de retour enfoncé aussi car le code de demande est renvoyé lors de l'événement.
la source
ajouter le mode de lancement en tant que tâche unique dans le manifeste pour éviter que l'activité s'ouvre deux fois en cliquant
la source
la source
Utilisez une
flag
variable pour le définirto true
, vérifiez si c'est vrai, maisreturn
effectuez un appel d'activité.Vous pouvez également utiliser setClickable (false) one pour exécuter l'appel d'activité
la source
perform click; wait; flg = false;
à notre retourVous pouvez simplement remplacer startActivityForResult et utiliser la variable d'instance:
la source
Vous pouvez essayer ceci aussi
la source