¿Es Dialog.show() un método sin bloqueo?

Tengo un botón que inicia un subproceso en segundo plano para hacer algo de trabajo y estoy tratando de usar un ProgressDialog para evitar que el usuario haga doble clic en ese botón (o en cualquier otro elemento de la interfaz de usuario) mientras se realiza ese trabajo. Lo primero que hago en mis botones onClick code es mostrar el cuadro de diálogo de progreso, que ocupa la pantalla. El problema que veo es que si toco rápidamente este botón, a veces se registran dos o más presiones antes de que se muestre ProgressDialog. Esto me lleva a suponer que ProgressDialog.show() regresa antes de que ProgressDialog sea realmente visible.

¿Alguien puede confirmar esto? Además, ¿hay alguna manera de cambiar este comportamiento, o al menos recibir una notificación de cuándo el cuadro de diálogo está realmente visible? Vi Dialog.onStart() pero dado el javadoc, parece que se llama antes de que el Diálogo sea realmente visible...

ACTUALIZACIÓN: Si bien parece que no hay una buena manera de resolver este problema en general, lo siguiente funciona para mi situación en la que mi trabajo lo realiza un subproceso externo y la cantidad de trabajo por hacer lleva más tiempo que el tiempo que lleva todo el clics de botón para ser procesados:

void myOnClickHandler() {
  if(myButton.isEnabled()) {
    myButton.setEnabled(False);
    // do work here
    // setEnabled(true) is invoked at the end of my spawned thread's run().
  }
}

preguntado el 22 de mayo de 12 a las 15:05

Por qué no setClickable(false) en su botón, justo dentro de onClick y después de terminar su progreso setClickable(true) ¿de nuevo? -

Estoy tratando de guardar eso como último recurso. El uso del cuadro de diálogo de progreso como mecanismo de bloqueo en realidad está integrado en el trabajo que se está realizando y me gustaría poder reutilizar ese mecanismo si es posible. -

@RafaelT y Jave: si bien suena genial, en realidad esto no le impide hacer clic en un botón más de una vez. Si hace clic lo suficientemente rápido, enviará varios clics antes de que se llame al controlador par real que deshabilita el botón. Por lo tanto, funciona en la mayoría de los casos, ya que la mayoría de los usuarios no intentarán hacer clic en los botones como locos... sin embargo, siempre tendrás a ese tipo... -

Estoy pensando que una posible solución podría ser setEnabled(false) combinado con envolver el trabajo del botón en un if (button.isEnabled() {...}. -

@Nick: una solución sería simplemente tener un objeto de tarea/hilo como variable miembro. Si ese objeto es nulo cuando ingresa su controlador onClick: use un bloque sincronizado para inicializar ese hilo/tarea asíncrona e inícielo. Si no es nulo cuando ingresa onClick, significa que ya comenzó a ejecutar su hilo y usted debería regresar de su controlador de clics sin hacer nada. -

2 Respuestas

No.

El problema es que hizo clic muchas veces antes de que se entregue el evento de clic. (es decir, está en cola antes de ejecutar ProgressDialog.show().)

contestado el 22 de mayo de 12 a las 15:05

Para mí, esto implica que setEnabled (falso) tampoco funcionará. ¿Hay alguna forma de protegerse contra esta situación sin escribir algún tipo de filtro en el código del controlador del botón que verifica las marcas de tiempo de los clics? - Nick

aceptado como la respuesta ya que esta fue la primera respuesta para caracterizar el problema subyacente. - Nick

Por lo que he notado en Android, puede hacer doble clic en un botón rápidamente y hacer que el oyente onClick se dispare dos veces (o incluso más) independientemente del código en el oyente (incluso si desactiva el botón inmediatamente).

Informé un error hace un tiempo aquí: http://code.google.com/p/android/issues/detail?id=20073 pero claro estas cosas suelen pasar "desapercibidas" por Google. Siéntase libre de destacarlo con la esperanza de llamar la atención de Google.

contestado el 22 de mayo de 12 a las 15:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.