I have a Button with an OnClickListener. For illustrative purposes, consider a button that shows a modal dialog:
public class SomeActivity ... {
protected void onCreate(Bundle state) {
super.onCreate(state);
findViewById(R.id.ok_button).setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
// This should block input
new AlertDialog.Builder(SomeActivity.this)
.setCancelable(true)
.show();
}
});
}
Under normal usage, the alert dialog appears and blocks further input. Users must dismiss the dialog before they can tap the button again.
But sometimes the button's OnClickListener is called twice before the dialog appears. You can duplicate this fairly easily by tapping really fast on the button. I generally have to try several times before it happens, but sooner or later I'll trigger multiple onClick(...) calls before the dialog blocks input.
I see this behavior in Android 2.1 on the Motorola Droid phone. We've received 4 crash reports in the Market, indicating this occasionally happens to people.
Depending on what our OnClickListeners do, this causes all sorts of havoc. How can we guarantee that blocking dialogs actually block input after the first tap?
Romain Guy confirmed that this is indeed a bug in Android: "It happens only if the user manages to press the button twice in < 125ms. I believe we fixed that possible error in Froyo."
We'll use the "glass pane" pattern to work around the bug on older OSes. That is, we'll cover the screen with an invisible view. After the first click event, we'll make the view "visible" so it intercepts subsequent touch events.
It's not enough to prevent further events on just the one button. You need to block all subsequent events for the entire activity until the dialog is dismissed, the activity is resumed, etc., at which point you make the glass pane "invisible" again.
If that doesn't work, we'll just have to live with this and better tolerate unexpected extra events.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With