In onCreateView() I've tried setting some properties, but the DialogFragment still goes away on tapping outside.
I would like the fragment to remain nearly all the time while the user interacts with other parts of the app.
This is in a class that extends BottomSheetDialogFragment:
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
// makes background non-interactive
getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
// prevents dimming of background
getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
// no effect?
getDialog().setCanceledOnTouchOutside(false);
this.setCancelable(false);
return view;
}
Code like:
public class MyDialogFragment extends DialogFragment {
...
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(...)
.setMessage(...)
.setCancelable(false);
...
Dialog dialog = builder.create();
dialog.getWindow();
return dialog;
}
...
}
works for me.
Related
I have a Bottom Sheet and I want to add a button in which the bottom sheet dialog expands on click
enter image description here
Is it doable to put onclicklistener inside bottom sheet fragment onCreateView and change the state of the dialog?
heres my Bottom Sheet Fragment
public class RepliesToComment extends BottomSheetDialogFragment {
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
Window window = dialog.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
dialog.getBehavior().setState(BottomSheetBehavior.STATE_COLLAPSED); <--change to STATE_EXPANDED on click-->
return dialog;
}
ImageButton expandBtn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_replies_to_comment, container, false);
{...}
expandBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
----
}
});
}
I manage to make it work heres my solution
dialog to global then made a boolean identifier to switch the state of the dialog
boolean identifier = true;
BottomSheetDialog dialog;
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
Window window = dialog.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
return dialog;
}
public void expand(){
if (!identifier){
dialog.getBehavior().setState(BottomSheetBehavior.STATE_COLLAPSED);
}else {
dialog.getBehavior().setState(BottomSheetBehavior.STATE_EXPANDED);
}
}
then made the button into toggle button to change the value of the identifier
//expand
expandBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
identifier = b;
expand();
}
});
I have a problem about Android dialog, most of the issues appears on Samsung devices, I'm not sure whether other devices have the same problem.
When a dialog(AlertDialog or DialogFragment) is shown, it has no focus and I can't click at anything on the dialog. It seems that focus is still on activity or fragment who creates the dialog, the activity/fragment below the dialog has response to my touch events.
I use this to create a AlertDialog
new AlertDialog.Builder(activity)
.setTitle(R.string.about_title)
.setMessage(buildAppInfo())
.setNegativeButton(R.string.app_ok, (dialog, which) -> dialog.dismiss())
.show());
This is my DialogFragment class:
public class MyDialog extends DialogFragment {
private MyDialogBinding binding;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog_NoActionBar_MinWidth);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.my_dialog, container, false);
binding.tvTitle.setText(R.string.dialog_title);
binding.tvMessage.setText(R.string.dialog_content);
binding.btnCancel.setOnClickListener(v -> dismiss());
return binding.getRoot();
}
#Override
public void show(#NonNull FragmentManager manager, String tag) {
if (!isAdded() && null == manager.findFragmentByTag(tag)) {
super.show(manager, tag);
}
}
}
And use this to create a DialogFragment
private final MyDialog dialog = new MyDialog();
dialog.show(getChildFragmentManager(), "");
Function setCancelableOnTouchOutside does not work. This issue occurs sometimes, when it occurs, I have to restart my app. Thank you very much in advance for your help.
I'm currently trying to use a custom layout with my DialogFragment, however it seems I'm doing something wrong. This is what my class currently looks like:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
setRetainInstance(true);
Log.d(TAG, "onCreateDialog");
return new AlertDialog.Builder(getActivity())
.setPositiveButton(android.R.string.ok, passDataListener)
.setNegativeButton(android.R.string.cancel, null)
.setCancelable(true)
.create();
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
setTitleFromBundle();
return inflater.inflate(R.layout.dialog_edittext, container);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mEditText = (EditText) view.findViewById(R.id.dialog_edittext);
tvUnits = (TextView) view.findViewById(R.id.dialog_units);
setMaxCharsFromBundle();
setTextFromBundle();
setHintFromBundle();
setInputTypeFromBundle();
setUnitsTextViewFromBundle();
}
The positive/negative buttons show (along with the title) however, my layout does not.
don't need to override onCreateView()
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
setRetainInstance(true);
Log.d(TAG, "onCreateDialog");
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return new AlertDialog.Builder(getActivity())
.setView(inflater.inflate(R.layout.dialog_edittext, null))
.setPositiveButton(android.R.string.ok, passDataListener)
.setNegativeButton(android.R.string.cancel, null)
.setCancelable(true)
.create();
}
You can't use both methods onCreateDialog and onCreateView at the same time. You have to choose if you want to show a "basic dialog" then overwrite onCreateDialog. If you want to show a "custom dialog" then overwrite onCreateView. Note that you can also overwrite onCreateDialog and set your own layout with youralertdialog.setView().
You should implement only one method between onCreateView and onCreateDialog, not both of them.
onCreateView : to supply the content of the dialog
onCreateDialog : to create an entirely custom dialog, such as an AlertDialog, with its own content
Everything is described in the documentation here
For a complete guide you can see https://guides.codepath.com/android/Using-DialogFragment
I try to bind ButterKnife to a AleterDialog that i made with a DialogBuilder method
And exist this method ButterKnife.bind(Object,Dialog); but dosen't work for me
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
public class NewUserDialogFragment extends DialogFragment {
#Bind(R.id.textuserAccount)
EditText textuserAccount;
#Bind(R.id.textPassword)
EditText textPassword;
#Bind(R.id.nauta_domains)
Spinner nauta_domains;
#Bind(R.id.manualConfig)
View manualConfig;
#Bind(R.id.checkViewPass)
CheckBox checkViewPass;
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog dialog = new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.new_user_dialog__icon)
.setTitle(R.string.new_user_dialog_title)
.setView(R.layout.accountlist_dialog_user_)
.setPositiveButton(R.string.alert_dialog_create, void_OnClickListener)
.setNegativeButton(R.string.alert_dialog_cancel, void_OnClickListener)
.create();
//Fails!!!!!!!
ButterKnife.bind(this,dialog);
...
ERROR:
Caused by: java.lang.IllegalStateException: Required view 'textuserAccount' with ID 2131624044 for field 'textuserAccount' was not found. If this view is optional add '#Nullable' annotation.
at butterknife.ButterKnife$Finder.findRequiredView(ButterKnife.java:140)
and textuserAccount = (EditText) ((Dialog) dialog).findViewById(R.id.textuserAccount); works perfectly
I can use butterknife somehow in this class?
You need to inflate your dialog layout and pass the resulting View object to butterknife.
view = View.inflate(getContext(), R.layout.accountlist_dialog_user_, null);
ButterKnife.bind(this, view);
At least, that's how I've used Butterknife in dialogs and it works fine for me.
I was able to bind views in onStart of the DialogFragment (similarly to this sample app), while still using the AlertDialog.Builder#setView(int) method:
private Unbinder unbinder;
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.new_user_dialog__icon)
.setTitle(R.string.new_user_dialog_title)
.setView(R.layout.accountlist_dialog_user)
.setPositiveButton(R.string.alert_dialog_create, void_OnClickListener)
.setNegativeButton(R.string.alert_dialog_cancel, void_OnClickListener)
.create();
}
#Override
public void onStart() {
super.onStart();
unbinder = ButterKnife.bind(this, getDialog());
}
#Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
And everything works perfect
Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.dialog_outcome);
Unbinder unbinder = ButterKnife.bind(this, dialog);
I'm trying to create an AlertDialog where both a message (in a TextView, for instance) and a MultiChoice-list can be displayed at the same time, but I'm a bit lost as to how to do it.
Will I have to create my own subclass of AlertDialog, or is there an easier way to do it?
You could create a normal AlertDialog but, instead of using the setMessage() method, you could just use a custom layout (you can inflate it in a View or even create a custom view) and use then the setView() method of the AlertDialog class.
Use DialogFragment for customization
public class ResponseDialog extends DialogFragment implements View.OnClickListener{
#Override
public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0);
getDialog().getWindow()
.getAttributes().windowAnimations = R.style.DialogAnimationFromDown;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Black_NoTitleBar);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
return dialog;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.YOUR_CUSTOM_LAYOUT, null);
//implement in layout what you want
return v;
}
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
}
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
}
}
}
for more info https://developer.android.com/reference/android/app/DialogFragment.html