DialogFragment onCreateView not returning custom layout view? - android

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

Related

Android dialog has no focus

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.

Fragment,DialogFragment Issue

I am calling dialog fragment from FragmentA and returning some values to fragmentA. Now issue is whenever i go to another fragmentB from same fragmentA and return to it my dialog fragment values get cleared.
when i click on consultant doctor textview, a dialog opens (Pic 2). On Selecting an item (Pic 2),returns a value back to FragmentA. Pic 3 is a Fragment B which opens on same activity. But when i click on cross button on pic 3 and popBackStack , my value for consult doctor clears shown in Pic 4.
Pic 4 is an ISSUE
DialogFragment
#Override
public void onStart() {
super.onStart();
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
getDialog().getWindow().setGravity(Gravity.CENTER);
getDialog().setCancelable(false);
getDialog().setCanceledOnTouchOutside(false);
getDialog().closeOptionsMenu();
}
#Override public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Nullable #Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
View rootView = inflater.inflate(R.layout.consultant_doc_dialog, container, false);
recyclerView = (RecyclerView)rootView.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(true);
adapter = new ConsultantDoctAdapter(getContext(),this);
adapter.getDocList().addAll(new ArrayList<DoctorList>());
recyclerView.setAdapter(adapter);
adapter.getDocList().clear();
adapter.getDocList().addAll(list);
adapter.notifyDataSetChanged();
close = (ImageButton)rootView.findViewById(R.id.bt_close);
close.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
getDialog().dismiss();
}
});
//cityEditText.setOnQueryTextListener(onQueryTextListener);
return rootView;
}
Fragment
#Nullable #Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_create_leads, container, false);
ButterKnife.bind(this, view);
setRetainInstance(true);
init();
setPicker();
setSpinnerListener();
btCheckCalendar.setOnClickListener(this);
etCityId.setOnClickListener(this);
etConsultingDocId.setOnClickListener(this);
btSubmit.setOnClickListener(this);
tvClientReferral.setOnClickListener(this);
etSalesPerson.setText(sharedPref.getString(AppConstants.PREFERENCE_USER_NAME, ""));
etZone.setText(sharedPref.getString(AppConstants.USER_ZONE, ""));
etAreaCode.setText(sharedPref.getString(AppConstants.USER_AREA_CODE, ""));
setSpinner();
getConsultantDoctorList();
return view;
}
Fragment B callBack:
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_main, new MyCalendarFragment())
.addToBackStack("calendarFragment")
.commit();
DialogCallack:
ConsultantDocDialogFragment consultantDocDialog = new ConsultantDocDialogFragment();
consultantDocDialog.setParameter(getContext(), this, doclist);
consultantDocDialog.show(getActivity().getSupportFragmentManager(),
ConsultantDocDialogFragment.class.getSimpleName());
break;
Please help me so that i can able to save state of values got from dialog fragment.
Please find the following code it may help you-
This is Fragment Code where you can get CallBack from Dialog Fragment-
HomeFragment.java
public class HomeFragment extends Fragment implements AlertDFragment.Callback {
private static final int DIALOG_FRAGMENT = 100;
Button alertdfragbutton;
private View rootView;
public HomeFragment() {
}
public static HomeFragment newInstance() {
return new HomeFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_home, container, false);
initUI(rootView);
return rootView;
}
private void initUI(View rootView) {
alertdfragbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
AlertDFragment alertdFragment = new AlertDFragment();
alertdFragment.setTargetFragment(HomeFragment.this, DIALOG_FRAGMENT);
// Show Alert DialogFragment
alertdFragment.show(getChildFragmentManager(), "Alert Dialog Fragment");
}
});
}
#Override
public void accept() {
Log.e("Home ", "OK");
}
#Override
public void decline() {
}
#Override
public void cancel() {
Log.e("Home ", "CANCEL");
}
}
Here is Dialog Fragment where we declare CallBack with methods-
public class AlertDFragment extends DialogFragment {
Callback callback;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
callback = (Callback) getTargetFragment();
return new AlertDialog.Builder(getActivity())
// Set Dialog Icon
.setIcon(R.drawable.androidhappy)
// Set Dialog Title
.setTitle("Alert DialogFragment")
// Set Dialog Message
.setMessage("Alert DialogFragment Tutorial")
// Positive button
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
callback.accept();
// Do something else
//getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, getActivity().getIntent());
}
})
// Negative Button
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
callback.cancel();
// Do something else
// getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_CANCELED, getActivity().getIntent());
}
}).create();
}
public static interface Callback {
public void accept();
public void decline();
public void cancel();
}
}
A simple way to return values from DialogFragment is using setTargetFragment for calling a fragmentB creation, then return data to getTargetFragment (if not null). In fragmentA you can receive data through onActivityResult.
Another way is using SharedPreferences. You can get a new value with onResume or onHiddenChanged.
Instead of using the "Fragment Transition" why don't you just POP-UP your custom view
Just Create a global reference of
Dialogue dialogue
View popupView
and on click of whatever textview button etc.
you can just call a method like
void popup(){
popupView = LayoutInflater.from(getActivity()).inflate(R.layout.your_calenderlayout, null);
//suppose you have TextView cal_textview in popUp view i.e, your_calenderlayout
cal_textview = (TextView ) popupView.findViewById(R.id.cal_textview);
dialog = new Dialog(getContext());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCanceledOnTouchOutside(true);
dialog.setContentView(popupView); //and just add your popUpview
// For setting backgroung
/*dialog.getWindow().setBackgroundDrawableResource(android.R.color.Transparent);
*/
//For setting the width or height of popup
/*WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(dialog.getWindow().getAttributes());
lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.gravity = Gravity.CENTER;
dialog.getWindow().setAttributes(lp);*/
dialog.show();
}
and on dismiss of popUp or on click of the view inside popupView you set the value of variables or member inside the fragment directly
Hope this will help
You can use Shared prefs or sqlite to get your values and if you think its use less to save your temporary data in share prefs or sqlite Then Singleton model is a good option .. i believe we should follow KISS
design principle :P

How can I make a BottomSheetDialogFragment non-modal?

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.

Bind ButterKnife to Dialog fails

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);

Create AlertDialog with both MultiChoiceItems and message

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

Categories

Resources