Android: how to dismiss a DatePicker DialogFragment when touching outside? - android

I have a working DatePickerFragment that extends DialogFragment. I set up a DatePickerDialog in onCreateDialog() and then tried to add:
"picker.setCanceledOnTouchOutside(true);"
I am testing on a device with Android 8.0 Oreo and nothing happens when touching outside the DatePicker dialog. I am using androidx.appcompat.app.AppCompatActivity as my BaseActivity and androidx.fragment.app.DialogFragment for the DialogFragment;
Code:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onCreateDialog(savedInstanceState);
DatePickerDialog picker = new DatePickerDialog(getActivity(),this,year,month,day);
**picker.setCanceledOnTouchOutside(true);**
return picker;
This is the Activity code that creates the Fragment:
DatePickerFragment newFragment = new DatePickerFragment();
// tried the below also, with no luck
**newFragment.setCancelable(true);**
newFragment.show(getSupportFragmentManager(), "datePicker");
I also tried the below in the DialogFragment, also with no luck:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
getDialog().setCanceledOnTouchOutside(true);
...
}
and:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (getDialog() != null) {
getDialog().setCanceledOnTouchOutside(true);
}
return super.onCreateView(inflater, container, savedInstanceState);
}
I referenced this post for possible answers: How to dismiss a DialogFragment when pressing outside the dialog?. What am I missing here?

if you want to dismiss Dialog that extends DialogFragment, write
setCancelable(true);
inside onCreateView. The dialog will dismiss when you touching outside.
example code :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setCancelable(true);
return super.onCreateView(inflater, container, savedInstanceState);
}

did you try to set the dialog to cancelable
picker.setCancelable(true);

I thought I have similar problem, but it seems in my case that dialog has some shadow padding around it and I had to click outside of it very close to the edge of the screen to cancel it.
This is how i create my dialog:
val calendar = Calendar.getInstance()
val year = calendar.get(Calendar.YEAR)
val month = calendar.get(Calendar.MONTH)
val day = calendar.get(Calendar.DAY_OF_MONTH)
val dpd = context?.let {
DatePickerDialog(it, DatePickerDialog.OnDateSetListener { _, pickedYear, pickedMonth, pickedDay ->
//do something with picked date.
}, year, month, day)
}
dpd?.setCanceledOnTouchOutside(true)
dpd?.show()
Try to set setCanceledOnTouchOutside(true) in your implementation and try to dismiss it on tap very close to the edge of the screen, maybe test it on some big screen emulator like Pixel 3 XL. Now i know that this is not a solution and you need to handle all kind of devices and screen sizes, but I want you to verify that you might have same problem as me: that dialog will be canceled on touch outside, but this "outside" is not so obvious and it might be a real problem.

Just add setCancelable(true) in your Dialog onCreate method or in constructor

Try to use the default DatePickerDialog from android which is default close when selecting out side the dialog.
Try this is still issue let me know will send the proper code for same

Related

How to show a Fragment in a Dialog?

I have created a fragment with some text and an image:
public class ContentFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_content, container, false);
return view;
}
}
Is there any way to get it to show in a dialog?
For example:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Showing a fragment in a dialog");
// Load fragment as dialog content somehow
AlertDialog alert = builder.create();
alert.show();
Every dialog has setView method which you can create programmatically or inflate, see this example
You should also consider to use a DialogFragment
AlertDialog is not supposed to host a fragment.
A workaround you can use is to replace dialog UI, which can be achieved by:
dialog.setContentView(R.layout.fragment_content)
This will just change the dialog view, if you want to bind events or data to the controls inside your fragment, you need to do it after setContentView

Dismiss Dialog Fragment when pressed outside

I use Dialog Fragment I extend it
public class DocumentLibrarySelectionFragment extends DialogFragment
I am not sure how to dismiss this dialog when the user presses outside it (I show this dialog inside my activity). I went through other related questions, but couldn't find complete answer, for example this How to dismiss a DialogFragment when pressing outside the dialog? here, where to add this lines of code in the first answer? Thanks.
In onCreateView, you can add DialogFragment.getDialog().setCanceledOnTouchOutside(true);
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
getDialog().setCanceledOnTouchOutside(true);
...
}

DialogFragment setCancelable property not working

I am working in an android application and am using a DialogFragment to show a dialog and I want to make that DialogFragment not cancelable. I have made the dialog cancelable property to false, but still its not affecting.
Please look into my code and suggest me a solution.
public class DialogTest extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return super.onCreateDialog(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_test, container, true);
getDialog().requestWindowFeature(STYLE_NO_TITLE);
getDialog().setCancelable(false);
return view;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_test, container, true);
getDialog().requestWindowFeature(STYLE_NO_TITLE);
getDialog().setCancelable(false);
return view;
}
instead of getDialog().setCancelable(false); you have to use directly setCancelable(false);
so the updated answer will be like this
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_test, container, true);
getDialog().requestWindowFeature(STYLE_NO_TITLE);
setCancelable(false);
return view;
}
Use the following Snippet
void showDialog() {
DialogFragment newFragment = MyAlertDialogFragment.newInstance(
R.string..alert_dialog_two_buttons_title);
newFragment.setCancelable(false);
newFragment.show(getFragmentManager(), "dialog");
}
and if you want to disable the out side touch around dialog use the following line of code
DialogFragment.getDialog().setCanceledOnTouchOutside(true);
In case you use alert builder (and probably in every case you wrap dialog inside a DialogFragment) to help build your dialog, please don't use getDialog().setCancelable(false) or Dialog.setCancelable(false) because it's not going to work.
Use setCancelable(false) as shown in code below as it's mentioned in oficial android documentation:
public void setCancelable (boolean cancelable)
Added in API level 11
Control whether the shown Dialog is cancelable. Use this instead of directly calling Dialog.setCancelable(boolean), because DialogFragment needs to change its behavior based on this."
ref:http://developer.android.com/reference/android/app/DialogFragment.html#setCancelable(boolean)
public class MyDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_layout, null, false);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle("in case you want use a title").setView(view);
AlertDialog alert = builder.create();
// alert.setCancelable(false); <-- dont' use that instead use bellow approach
setCancelable(false); <- press back button not cancel dialog, this one works fine
alert.setCanceledOnTouchOutside(false); <- to cancel outside touch
return alert;
}
Simple Solution in DialogFragment
Used
dialog.setCanceledOnTouchOutside(false)
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
AlertDialog.Builder(activity!!).apply {
isCancelable = false
setMessage("Your message")
// your other adjustments
return this.create()
}
}
worked for me.
The main thing is to use isCancelable = false over setCancellable(false)
within override fun onCreateDialog().
/**
* Control whether the shown Dialog is cancelable. Use this instead of
* directly calling {#link Dialog#setCancelable(boolean)
* Dialog.setCancelable(boolean)}, because DialogFragment needs to change
* its behavior based on this.
*
* #param cancelable If true, the dialog is cancelable. The default
* is true.
*/
DialogFragment.setCancelable(boolean cancelable) {
mCancelable = cancelable;
if (mDialog != null) mDialog.setCancelable(cancelable);
}

Android DialogFragment: How to preserve view in multiple show() invocation?

I have a dialog fragment using a custom layout with a quite complex View hierarchy. The code for the dialog fragment is more or less similar to the following.
public class CardDetailDialog extends DialogFragment {
public CardDetailDialog() {
setRetainInstance(true);
setStyle(STYLE_NORMAL, android.R.style.Theme_Light);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.card_detail_dialog, container, false);
/* Modify some view objects ... */
return view;
}
}
Whenever I invoked the show() method for this dialog fragment, I noticed that onCreateView is always called and layout inflation process is repeated. In my app, user might want to show the dialog multiple times during a session and I thought this is inefficient. Is there any way to keep the view / dialog instance across multiple show() invocation? Is it possible to do this using DialogFragment, or do I have to deal directly with Dialog class?
Using a boolean flag seems to do the trick (See the KEY CHANGEs). I override onCreateDialog, but employing the same strategy in onCreateView should work as well (keep a reference to your view you create)
I'm still getting some issues related to Orientation changes, but it may be related to a different issue
public class LogFragment extends DialogFragment{
private boolean isCreated; //KEY CHANGE
private Dialog mDialog; //KEY CHANGE -- to hold onto dialog instance across show()s
public LogFragment() {
setRetainInstance(true); // This keeps the fields across activity lifecycle
isCreated = false; // KEY CHANGE - we create the dialog/view the 1st time
}
#Override
public Dialog onCreateDialog(Bundle inState) {
if (isCreated) return mDialog; // KEY CHANGE - don't recreate, just send it back
View v = View.inflate(getActivity(),R.layout.log_layout,null);
mDialog = new AlertDialog.Builder(getActivity())
...
.create();
isCreated = true; // KEY CHANGE Set the FLAG
return mDialog;
}

How to dismiss a DialogFragment when pressing outside the dialog?

I am using a DialogFragment, and while I have successfully set an image to close (i.e. dismiss) the dialog when pressed, I am having a hard time finding the way to dismiss the dialog when the user clicks anywhere outside it, just as it works with normal dialogs. I thought there would be some sort of
dialogFragment.setCanceledOnTouchOutside(true);
call, but I don't see that in the documentation.
Is this possible with DialogFragment at all? Or am I looking in the wrong places? I tried intercepting touch events in the 'parent' activity but apart from not getting any touch event, it didn't seem right to me.
DialogFragment.getDialog().setCanceledOnTouchOutside(true);
Must be called in onCreateView (as Apurv Gupta pointed out).
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
getDialog().setCanceledOnTouchOutside(true);
...
}
/** The system calls this only when creating the layout in a dialog. */
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// The only reason you might override this method when using onCreateView() is
// to modify any dialog characteristics. For example, the dialog includes a
// title by default, but your custom layout might not need it. So here you can
// remove the dialog title, but you must call the superclass to get the Dialog.
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCanceledOnTouchOutside(true);
return dialog;
}
Lot of answers here but, the app crash when dialog opens.
Writing getDialog().setCanceledOnTouchOutside(true); inside onCreateView did not work and crashed my app.
(I am using AppCompatActivity as my BaseActivity and android.app.DialogFragment as my Fragment).
What works is either of the two following lines:
getDialog().setCanceledOnTouchOutside(true);
OR
this.getDialog().setCanceledOnTouchOutside(true);
inside onActivityCreated like
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//getDialog().getWindow().getAttributes().windowAnimations = R.style.DialogAnimationZoom;
//getDialog().getWindow().setDimAmount(0.85f);
getDialog().setCanceledOnTouchOutside(true);//See here is the code
}
What not to use:
DialogFragment.getDialog().setCanceledOnTouchOutside(false);
throws following error
And writing the code in onCreateView crashes the App!
Please update the answer if you find something wrong.
If you want to execute some logic when clicking outside of a DialogFragment, just override the onCancel method.
override fun onCancel(dialog: DialogInterface) {
super.onCancel(dialog)
// Do your work here
}
This works fine for Java:
DialogFragment.getDialog().setCanceledOnTouchOutside(false);
I would recommend to use my solution only after trying out above solutions. I have described my solution here. Just to brief, I am checking touch bounds of DialogFragment.getView(). When touch points are outside DialogFragment, I am dismissing the Dialog.
Dialog.SetCanceledOnTouchOutside(true);
Worked for me
My Code
class dlgRegister : DialogFragment
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
....
....
}
public override void OnActivityCreated(Bundle savedInstanceState)
{
Dialog.Window.RequestFeature(WindowFeatures.NoTitle);
Dialog.SetCanceledOnTouchOutside(true);
base.OnActivityCreated(savedInstanceState);
Dialog.Window.Attributes.WindowAnimations = Resource.Style.dialog_animation;
}
}
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup
container, #Nullable Bundle savedInstanceState)
{
DialogConfermationdialogBinding binding = DialogConfermationdialogBinding.inflate(inflater,container,false);
View view = binding.getRoot();
getDialog().setCanceledOnTouchOutside(false);
return view;
}

Categories

Resources