StackOverflowError when trying to inflate a custom layout for an AlertDialog inside a DialogFragment
Asked Answered
J

3

21

I'm trying to create an AlertDialog, by using the Builder and setting a custom view. When I try to inflate the view inside of onCreateDialog, I get a StackOverflowError..

Here is the code up to the point where it loops back to onCreateDialog:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle(R.string.enter_time);

    LinearLayout outerLayout = (LinearLayout) getLayoutInflater(savedInstanceState)
            .inflate(R.layout.time_entry_dialog, null);
    ...
}

And here is the LogCat output:

02-28 22:30:04.220: E/AndroidRuntime(4250): FATAL EXCEPTION: main
02-28 22:30:04.220: E/AndroidRuntime(4250): java.lang.StackOverflowError
02-28 22:30:04.220: E/AndroidRuntime(4250):     at android.app.Activity.getSystemService(Activity.java:4009)
02-28 22:30:04.220: E/AndroidRuntime(4250):     at android.view.LayoutInflater.from(LayoutInflater.java:210)
02-28 22:30:04.220: E/AndroidRuntime(4250):     at android.view.ContextThemeWrapper.getSystemService(ContextThemeWrapper.java:75)
02-28 22:30:04.220: E/AndroidRuntime(4250):     at com.android.internal.app.AlertController$AlertParams.<init>(AlertController.java:812)
02-28 22:30:04.220: E/AndroidRuntime(4250):     at android.app.AlertDialog$Builder.<init>(AlertDialog.java:374)
02-28 22:30:04.220: E/AndroidRuntime(4250):     at android.app.AlertDialog$Builder.<init>(AlertDialog.java:359)
02-28 22:30:04.220: E/AndroidRuntime(4250):     at com.sweatyreptile.chee.runtimetracker.TimeEntryDialogFragment.onCreateDialog(TimeEntryDialogFragment.java:18)
02-28 22:30:04.220: E/AndroidRuntime(4250):     at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:295)
02-28 22:30:04.220: E/AndroidRuntime(4250):     at com.sweatyreptile.chee.runtimetracker.TimeEntryDialogFragment.onCreateDialog(TimeEntryDialogFragment.java:21)
02-28 22:30:04.220: E/AndroidRuntime(4250):     at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:295)
02-28 22:30:04.220: E/AndroidRuntime(4250):     at com.sweatyreptile.chee.runtimetracker.TimeEntryDialogFragment.onCreateDialog(TimeEntryDialogFragment.java:21)
02-28 22:30:04.220: E/AndroidRuntime(4250):     at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:295)
...etc

EDIT: I found this line in the source of DialogFragment.getLayoutInflater():

mDialog = onCreateDialog(savedInstanceState);

So.. if I can't get a LayoutInflator inside of onCreateDialog without causing infinite recursion, how do I inflate a view for a custom AlertDialog?

Jocund answered 1/3, 2013 at 6:21 Comment(3)
What do you have in the time_entry_dialog? Also don't be afraid to post the stacktrace with the exception.Ingratiate
Please add your Logcat outputParaboloid
I added the LogCat output. @Luksprog, time_entry_dialog is just a LinearLayout with centered gravityJocund
J
34

If found the problem. DialogFragment.getLayoutInflater() contains a call to onCreateDialog(), so calling onCreateDialog() from within getLayoutInflater() creates an infinite loop.

I found the solution in this answer: https://mcmap.net/q/545953/-dialogfragment-using-alertdialog-with-custom-layout

I'm not exactly sure if this is good form, because it doesn't really seem like it, but I replaced

getLayoutInflater(savedInstanceState)

with

getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

Edit: They are the same. See this answer for details: https://mcmap.net/q/432585/-what-is-the-correct-way-to-get-layout-inflater-in-android

Jocund answered 1/3, 2013 at 7:35 Comment(5)
Is that an Android bug? I had this problem too, and to me calling onCreateDialog from within getLayoutInflater doesn't make sense?Paucker
LayoutInflater.from(getContext()) seems to work as well.Absalom
getActivity().getLayoutInflater() also works, although you should also check for getActivity() returning null if you're using a v4 support library Fragment. See developer.android.com/reference/android/support/v4/app/…Nonconductor
Disappointing that 5 years later, the Android docs still guide people to use the wrong method: layoutInflater.inflate(...) developer.android.com/guide/topics/ui/dialogs#kotlinHootenanny
Both LayoutInflater.from(getContext()) and getActivity().getLayoutInflater() are working.Derwood
P
1

It looks like this is fixed in Fragment 1.2.3: https://developer.android.com/jetpack/androidx/releases/fragment#1.2.3.

The docs do use requireActivity().getLayoutInflater() rather than just getLayoutInflater however so it still might not be recommended.

Phenformin answered 15/5, 2020 at 9:58 Comment(0)
A
1

You should use LayoutInflater.from(getContext()).

If you are using viewbindings you can call it like this:

binding = FragmentOtpDialogBinding.inflate(LayoutInflater.from(getContext()));

Agoraphobia answered 15/8, 2020 at 8:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.