diff options
| author | Dianne Hackborn <hackbod@google.com> | 2011-01-18 13:57:54 -0800 |
|---|---|---|
| committer | Dianne Hackborn <hackbod@google.com> | 2011-01-18 15:28:41 -0800 |
| commit | cfaf8878de83b6bb7a24aee3c240259f428e6e4a (patch) | |
| tree | 94b5ce5d527514de1854a3f73bf0fd7208534dcb /core/java | |
| parent | 60610d245f899c8c48ba6c7e94c0a20010fc6eed (diff) | |
Fix issue #3362484: Can't dismiss activity picker by tapping outside dialog
Change-Id: Idc2fe5a86c61e8f94fe9d902a0087a05f6f7918e
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/app/Activity.java | 13 | ||||
| -rw-r--r-- | core/java/android/app/AlertDialog.java | 21 | ||||
| -rw-r--r-- | core/java/android/app/Dialog.java | 22 | ||||
| -rw-r--r-- | core/java/android/view/Window.java | 35 |
4 files changed, 52 insertions, 39 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index ec2f771cd984..9ec187fb4d95 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -1806,6 +1806,14 @@ public class Activity extends ContextThemeWrapper } /** + * Sets whether this activity is finished when touched outside its window's + * bounds. + */ + public void setFinishOnTouchOutside(boolean finish) { + mWindow.setCloseOnTouchOutside(finish); + } + + /** * Use with {@link #setDefaultKeyMode} to turn off default handling of * keys. * @@ -2061,6 +2069,11 @@ public class Activity extends ContextThemeWrapper * The default implementation always returns false. */ public boolean onTouchEvent(MotionEvent event) { + if (mWindow.shouldCloseOnTouch(this, event)) { + finish(); + return true; + } + return false; } diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java index 70e36165d3d8..428f4e3d4b3f 100644 --- a/core/java/android/app/AlertDialog.java +++ b/core/java/android/app/AlertDialog.java @@ -64,11 +64,13 @@ public class AlertDialog extends Dialog implements DialogInterface { protected AlertDialog(Context context, int theme) { super(context, theme == 0 ? getDefaultDialogTheme(context) : theme); + mWindow.alwaysReadCloseOnTouchAttr(); mAlert = new AlertController(context, this, getWindow()); } protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) { super(context, getDefaultDialogTheme(context)); + mWindow.alwaysReadCloseOnTouchAttr(); setCancelable(cancelable); setOnCancelListener(cancelListener); mAlert = new AlertController(context, this, getWindow()); @@ -81,25 +83,6 @@ public class AlertDialog extends Dialog implements DialogInterface { return outValue.resourceId; } - @Override - public boolean onTouchEvent(MotionEvent ev) { - if (mCancelable) { - final View decor = mWindow.getDecorView(); - final int width = decor.getWidth(); - final int height = decor.getHeight(); - final float x = ev.getX(); - final float y = ev.getY(); - - if (mCancelable && (x < 0 || x > width || y < 0 || y > height) - && mDecor != null && isShowing()) { - cancel(); - return true; - } - } - - return super.onTouchEvent(ev); - } - /** * Gets one of the buttons used in the dialog. * <p> diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java index 6791400a0055..7365670a9aaa 100644 --- a/core/java/android/app/Dialog.java +++ b/core/java/android/app/Dialog.java @@ -41,7 +41,6 @@ import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnCreateContextMenuListener; -import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.Window; @@ -90,12 +89,6 @@ public class Dialog implements DialogInterface, Window.Callback, private Message mDismissMessage; private Message mShowMessage; - /** - * Whether to cancel the dialog when a touch is received outside of the - * window's bounds. - */ - private boolean mCanceledOnTouchOutside = false; - private OnKeyListener mOnKeyListener; private boolean mCreated = false; @@ -597,8 +590,7 @@ public class Dialog implements DialogInterface, Window.Callback, * happens outside of the window bounds. */ public boolean onTouchEvent(MotionEvent event) { - if (mCancelable && mCanceledOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN - && isOutOfBounds(event) && mDecor != null && mShowing) { + if (mCancelable && mShowing && mWindow.shouldCloseOnTouch(mContext, event)) { cancel(); return true; } @@ -606,16 +598,6 @@ public class Dialog implements DialogInterface, Window.Callback, return false; } - private boolean isOutOfBounds(MotionEvent event) { - final int x = (int) event.getX(); - final int y = (int) event.getY(); - final int slop = ViewConfiguration.get(mContext).getScaledWindowTouchSlop(); - final View decorView = getWindow().getDecorView(); - return (x < -slop) || (y < -slop) - || (x > (decorView.getWidth()+slop)) - || (y > (decorView.getHeight()+slop)); - } - /** * Called when the trackball was moved and not handled by any of the * views inside of the activity. So, for example, if the trackball moves @@ -1021,7 +1003,7 @@ public class Dialog implements DialogInterface, Window.Callback, mCancelable = true; } - mCanceledOnTouchOutside = cancel; + mWindow.setCloseOnTouchOutside(cancel); } /** diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 2f27935dd331..f1883dc2af42 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -116,6 +116,8 @@ public abstract class Window { private Window mActiveChild; private boolean mIsActive = false; private boolean mHasChildren = false; + private boolean mCloseOnTouchOutside = false; + private boolean mSetCloseOnTouchOutside = false; private int mForcedWindowFlags = 0; private int mFeatures = DEFAULT_FEATURES; @@ -786,6 +788,39 @@ public abstract class Window { return mHasSoftInputMode; } + /** @hide */ + public void setCloseOnTouchOutside(boolean close) { + mCloseOnTouchOutside = close; + mSetCloseOnTouchOutside = true; + } + + /** @hide */ + public boolean hasSetCloseOnTouchOutside() { + return mSetCloseOnTouchOutside; + } + + /** @hide */ + public abstract void alwaysReadCloseOnTouchAttr(); + + /** @hide */ + public boolean shouldCloseOnTouch(Context context, MotionEvent event) { + if (mCloseOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN + && isOutOfBounds(context, event) && peekDecorView() != null) { + return true; + } + return false; + } + + private boolean isOutOfBounds(Context context, MotionEvent event) { + final int x = (int) event.getX(); + final int y = (int) event.getY(); + final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop(); + final View decorView = getDecorView(); + return (x < -slop) || (y < -slop) + || (x > (decorView.getWidth()+slop)) + || (y > (decorView.getHeight()+slop)); + } + /** * Enable extended screen features. This must be called before * setContentView(). May be called as many times as desired as long as it |
