Reputation: 9995
I have searched through all the answers about dismissing a Dialog onTouchOutside, however, I am using DialogFragment in my application. How can I achieve dismissing the DialogFragment when user clicks outside the DialogFragment's region.
I have examined Dialog's source code for setCanceledOnTouchOutside
public void setCanceledOnTouchOutside(boolean cancel) {
if (cancel && !mCancelable) {
mCancelable = true;
}
mCanceledOnTouchOutside = cancel;
}
There's another function which may be interesting which is isOutOfBounds
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));
}
but I couldn't figure out a way to make use of these for DialogFragment
In addition to these I have examined the state of the application with hierarchyviewer and as I understand it, I can only see the region of the dialog and not the outsied part of it (I mean the remaining part of the screen after the DialogFragment).
Can you suggest a way of implementing this setCanceledOnTouchOutside for DialogFragment and if possible with a sample code?
Upvotes: 20
Views: 16055
Reputation: 572
I have answered to another question, but that answer is more appropriate for this problem, My solution . Just to brief here, I simply implemented onTouch()
of DialogFragment
's getView()
and checked touch bounds.
Upvotes: 0
Reputation: 1255
Why not just override onCreateDialog
and just set it there. That way you don't have to check for null on the getDialog()
call all the time.
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog d = super.onCreateDialog(savedInstanceState);
d.setCanceledOnTouchOutside(false);
return d;
}
Upvotes: 5
Reputation: 4965
In most cases, getDialog() is null, since you won't get it immediately after you make a new instance of your dialog.
As suggested above onViewCreated
is also nor correct for DialogFragment
especially when using android.support.v4.app.DialogFragment
.
The below works well, as it's placed on the onCreateView
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (getDialog() != null) {
getDialog().setCanceledOnTouchOutside(true);
}
return super.onCreateView(inflater, container, savedInstanceState);
}
Upvotes: 11
Reputation: 560
I was reading: http://developer.android.com/reference/android/app/DialogFragment.html
It states: "Control of the dialog (deciding when to show, hide, dismiss it) should be done through the API here, not with direct calls on the dialog."
Upvotes: 0
Reputation: 3448
The answer is pretty simple:
MyDialogFragment fragment = new MyDialogFragment(); // init in onCreate() or somewhere else
...
if ( fragment.getDialog() != null )
fragment.getDialog().setCanceledOnTouchOutside(true); // after fragment has already dialog, i. e. in onCreateView()
See http://developer.android.com/reference/android/app/DialogFragment.html#setShowsDialog%28boolean%29 for more info about dialogs in DialogFragments.
Upvotes: 37