Estou tentando evitar que a atividade carregue duas vezes se pressiono o botão duas vezes imediatamente após o primeiro clique.
Tenho uma atividade que carrega com o clique de um botão, digamos
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//Load another activity
}
});
Agora, como a atividade a ser carregada possui chamadas de rede, leva um pouco de tempo para carregar (MVC). Eu mostro uma visualização de carregamento para isso, mas se eu pressionar o botão duas vezes antes disso, posso ver a atividade sendo carregada duas vezes.
Alguém sabe como evitar isso?
Respostas:
No ouvinte de evento do botão, desative o botão e mostre outra atividade.
Substitua
onResume()
para reativar o botão.fonte
Adicione isso à sua
Activity
definição emAndroidManifest.xml
...Por exemplo:
fonte
android:launchMode = "singleTop"
, que atinge o efeito sem quebrar a multitarefa do Android. A documentação afirma que a maioria dos aplicativos não deve usar asingleInstance
opção.Você pode usar os sinalizadores de intent assim.
Isso fará com que apenas uma atividade seja aberta no topo da pilha de histórico.
fonte
android:launchMode = "singleTop"
desta forma é resolvido sem ter que adicionar o sinalizador a todos os Intent.Já que o SO não me permite comentar sobre outras respostas, tenho que poluir este tópico com uma nova resposta.
Respostas comuns para o problema "atividade abre duas vezes" e minhas experiências com essas soluções (Android 7.1.1):
EDIT: Isso era para iniciar atividades com startActivity (). Ao usar startActivityForResult (), preciso definir FLAG_ACTIVITY_SINGLE_TOP e FLAG_ACTIVITY_CLEAR_TOP.
fonte
Só estava funcionando para mim quando
startActivity(intent)
fonte
android:launchMode = "singleInstance"
ao arquivo Manifest da sua tag de atividade?Use singleInstance para evitar que a atividade seja chamada duas vezes.
fonte
Digamos que @wannik esteja certo, mas se tivermos mais de 1 botão chamando o mesmo ouvinte de ação e eu clicar em dois botões quase ao mesmo tempo antes de iniciar a próxima atividade ...
Portanto, é bom se você tiver campo
private boolean mIsClicked = false;
e no ouvinte:E
onResume()
precisamos retornar o estado:Qual é a diferença entre a minha resposta e a de @wannik?
Se você definir enabled como false no ouvinte de sua exibição de chamada, outro botão usando o mesmo ouvinte ainda estará ativado. Portanto, para ter certeza de que a ação do ouvinte não será chamada duas vezes, você precisa ter algo global que desative todas as chamadas do ouvinte (esqueça se é uma nova instância ou não)
Qual é a diferença entre minha resposta e outras?
Eles estão pensando da maneira certa, mas não estão pensando em um futuro retorno à mesma instância da atividade de chamada :)
fonte
synchronized(mIsClicked) {...}
para estar 100% seguro.Para esta situação, irei para um dos dois abordados,
singleTask
em manifest.xml OU um sinalizador noonResume()
&onDestroy()
métodos respectivamente.Para a primeira solução: prefiro usar
singleTask
para a atividade no manifesto em vez desingleInstance
, conforme o usosingleInstance
, descobri que, em algumas ocasiões, a atividade cria uma nova instância separada para si mesma, o que resulta em ter uma janela de dois aplicativos separados nos aplicativos em execução no bcakground e além de alocações de memória extra que resultariam em uma experiência do usuário muito ruim quando o usuário abre a visualização de aplicativos para escolher algum aplicativo para retomar. Portanto, a melhor maneira é ter a atividade definida no manifest.xml da seguinte forma:você pode verificar os modos de inicialização da atividade aqui .
Pelo segundo solução, você deve apenas definir uma variável estática ou uma variável de preferência, por exemplo:
e do outro lado quando você quiser iniciar esta atividade, basta verificar:
fonte
Acho que você está resolvendo o problema da maneira errada. Geralmente é uma má idéia para uma atividade a ser tomada de longa execução solicitações da web em qualquer um dos seus métodos de ciclo de vida de inicialização (
onCreate()
,onResume()
, etc). Na verdade, esses métodos devem ser usados simplesmente para instanciar e inicializar objetos que sua atividade usará e, portanto, devem ser relativamente rápidos.Se você precisar realizar uma solicitação da web, faça isso em um thread de segundo plano de sua atividade recém-iniciada (e mostre a caixa de diálogo de carregamento na nova atividade). Depois que o thread de solicitação em segundo plano é concluído, ele pode atualizar a atividade e ocultar a caixa de diálogo.
Isso significa que sua nova atividade deve ser iniciada imediatamente e evitar que o clique duplo seja possível.
fonte
Espero que isto ajude:
fonte
Outra solução muito simples caso não queira usar
onActivityResult()
é desabilitar o botão por 2 segundos (ou o tempo que quiser), não é o ideal, mas pode resolver parcialmente o problema em alguns casos e o código é simples:fonte
// variável para rastrear o tempo do evento
2. No onClick, verifique se o horário atual e a diferença de horário do último clique são inferiores a um segundo, então não faça nada (retorne), vá para o evento de clique
fonte
Basta manter um sinalizador no método onClick do botão como:
public boolean oneTimeLoadActivity = false;
fonte
Se você estiver usando onActivityResult, poderá usar uma variável para salvar o estado.
Funciona com o botão Voltar pressionado também porque o código de solicitação é retornado no evento.
fonte
adicione o modo de inicialização como tarefa única no manifesto para evitar que a atividade abra duas vezes ao clicar
fonte
fonte
Use uma
flag
variável para configurá-lato true
, verifique se ela é verdadeira apenasreturn
execute uma chamada de atividade.Você também pode usar setClickable (false) executando a chamada de atividade
fonte
perform click; wait; flg = false;
para quando voltarmosVocê pode simplesmente substituir startActivityForResult e usar a variável de instância:
fonte
Você pode tentar isso também
fonte