Estoy tratando de evitar que la actividad se cargue dos veces si presiono el botón dos veces instantáneamente después del primer clic.
Tengo una actividad que se carga al hacer clic en un botón, digamos
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//Load another activity
}
});
Ahora que la actividad que se va a cargar tiene llamadas de red, se tarda un poco en cargar (MVC). Muestro una vista de carga para esto, pero si presiono el botón dos veces antes de eso, puedo ver que la actividad se carga dos veces.
¿Alguien sabe cómo prevenir esto?
Respuestas:
En el detector de eventos del botón, desactive el botón y muestre otra actividad.
Anular
onResume()
para volver a habilitar el botón.fuente
Agregue esto a su
Activity
definición enAndroidManifest.xml
...Por ejemplo:
fuente
android:launchMode = "singleTop"
, que logra el efecto sin romper la multitarea de Android. La documentación indica que la mayoría de las aplicaciones no deberían usar lasingleInstance
opción.Puede usar los indicadores de intención de esta manera.
Hará que solo una actividad esté abierta en la parte superior de la pila del historial.
fuente
android:launchMode = "singleTop"
esta manera se resuelve sin tener que agregar la bandera a cada Intent.Como SO no me permite comentar sobre otras respuestas, tengo que contaminar este hilo con una nueva respuesta.
Respuestas comunes para el problema "la actividad se abre dos veces" y mis experiencias con estas soluciones (Android 7.1.1):
EDITAR: Esto fue para iniciar actividades con startActivity (). Cuando uso startActivityForResult (), necesito configurar FLAG_ACTIVITY_SINGLE_TOP y FLAG_ACTIVITY_CLEAR_TOP.
fuente
Solo funcionaba para mí cuando
startActivity(intent)
fuente
android:launchMode = "singleInstance"
en el archivo de manifiesto de su etiqueta de actividad?Use singleInstance para evitar que la actividad se invoque dos veces.
fuente
Digamos que @wannik tiene razón, pero si tenemos más de 1 botón llamando al mismo oyente de acción y hago clic en dos botones una vez casi al mismo tiempo antes de comenzar la siguiente actividad ...
Entonces es bueno si tiene un campo
private boolean mIsClicked = false;
y en el oyente:Y
onResume()
necesitamos devolver el estado:¿Cuál es la diferencia entre mi respuesta y la de @ wannik?
Si establece habilitado en falso en el oyente de su llamada, ver otro botón que usa el mismo oyente aún estará habilitado. Entonces, para asegurarse de que la acción del oyente no se llame dos veces, debe tener algo global que deshabilite todas las llamadas del oyente (no importa si es una nueva instancia o no)
¿Cuál es la diferencia entre mi respuesta y otras?
Están pensando de la manera correcta, pero no están pensando en regresar en el futuro a la misma instancia de la actividad de llamada :)
fuente
synchronized(mIsClicked) {...}
para estar 100% seguro.Para esta situación, elegiré uno de los dos abordados,
singleTask
en manifest.xml O una bandera en los métodosonResume()
& de la ActividadonDestroy()
respectivamente.Para la primera solución: prefiero usar
singleTask
para la actividad en el manifiesto en lugar desingleInstance
, según el usosingleInstance
, descubrí que en algunas ocasiones la actividad crea una nueva instancia separada para sí misma, lo que da como resultado una ventana de dos aplicaciones separadas en las aplicaciones en ejecución en bcakground y además de asignaciones de memoria extra que resultarían en una experiencia de usuario muy mala cuando el usuario abre la vista de aplicaciones para elegir alguna aplicación para reanudar. Entonces, la mejor manera es tener la actividad definida en el manifest.xml como se muestra a continuación:puedes consultar los modos de inicio de actividad aquí .
Para la segunda solución, solo tiene que definir una variable estática o una variable de preferencia, por ejemplo:
y desde el otro lado, cuando desee iniciar esta actividad, simplemente marque:
fuente
Creo que estás resolviendo el problema de manera incorrecta. En general es una mala idea para una actividad que se va haciendo larga ejecución peticiones web en cualquiera de sus métodos de puesta en marcha del ciclo de vida (
onCreate()
,onResume()
, etc.). Realmente, estos métodos deberían usarse simplemente para crear instancias e inicializar objetos que su actividad usará y, por lo tanto, deberían ser relativamente rápidos.Si necesita realizar una solicitud web, hágalo en un hilo de fondo de su actividad recién iniciada (y muestre el diálogo de carga en la nueva actividad). Una vez que se completa el hilo de solicitud en segundo plano, puede actualizar la actividad y ocultar el diálogo.
Esto significa que su nueva actividad debe iniciarse de inmediato y evitar que el doble clic sea posible.
fuente
Espero que esto ayude:
fuente
Otra solución muy muy simple si no quieres usar
onActivityResult()
es deshabilitar el botón por 2 segundos (o el tiempo que quieras), no es lo ideal, pero puede solucionar en parte el problema en algunos casos y el código es simple:fuente
// variable para rastrear el tiempo del evento
2.En onClick, compruebe que si la hora actual y la diferencia de tiempo del último clic son menos de un segundo, no haga nada (regresar), de lo contrario, vaya al evento de clic
fuente
Simplemente mantenga una bandera en el botón onClick método como:
public boolean oneTimeLoadActivity = false;
fuente
Si está usando onActivityResult, podría usar una variable para guardar el estado.
También funciona con el botón Atrás presionado porque el código de solicitud se devuelve en el evento.
fuente
agregue el modo de inicio como una sola tarea en el manifiesto para evitar que la actividad se abra dos veces al hacer clic
fuente
fuente
Use una
flag
variableto true
, configúrelo, verifique si es cierto, soloreturn
realice una llamada de actividad.También puede usar setClickable (false) one ejecutando la llamada de actividad
fuente
perform click; wait; flg = false;
para cuando volvamosPuede simplemente anular startActivityForResult y usar la variable de instancia:
fuente
Puedes probar esto también
fuente