ViewPager in DialogFragment - IllegalStateException: Fragment does not have a view

I think I just ran into this same problem and learned a few things by looking at the source for DialogFragment.

It looks like even though overriding onCreateDialog(...) is a valid way to create a custom dialog, it will result in the DialogFragment having a null View, just like the error message says. In most cases this is fine - the DialogFragment doesn't need a View to show a Dialog, but if you want to nest fragments further (like you do), this won't fly.

Considering that you want to interact with an AlertDialog.Builder, there is really no perfect solution that I can see, but you've got a few options:

  1. Create the buttons in your dialog as part of the View (not using AlertDialog.Builder). You do this by overriding onCreateView instead of onCreateDialog. You should be able to get the functionality you mention by putting the buttons in their own fragment. We do something similar at my gig, and I very much prefer this method.
  2. Implement your own type that inherits from Fragment and that mirrors the DialogFragment in every way except allowing what you need. This shouldn't be too scary as DialogFragment is only ~400 and is heavily commented. Could be fun.
  3. Use a regular PagerAdapter instead of a FragmentPagerAdapter. This way it won't matter that your DialogFragment doesn't have a View.

Use the

onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)

instead of onCreateDialog(Bundle savedInstanceState). Don't create an alert dialog, use the inflater provided by the method, and build your view. It works for me.

Best regards!

Thanks to @Tommy Visic for writing a really good description it worked.

Posting the code which worked for me.

I have removed the Dialog building code from the onCreateDialog method infact removed onCreateDialog method and the dialog view which I have been implementing in the Dialog's custom view I have included it as a View in the onCreateView method and all the things started working.

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.login_sigup_screen, null, false);
    bind = ButterKnife.bind(this, view);
    initViewPager();
    return view;
}

Faced one more problem with this implementation is:

When a Activity has Toolbar/ActionBar then it is also displayed into the DialogFragment to avoid that what is to be done is: Implement onViewCreated method of Fragment and add below code

Dialog dialog = getDialog();
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
float dimAmount = 0.6f;
dialog.getWindow().setDimAmount(dimAmount);

This will remove the Toolbar from the DialogFragment and Activity will be displayed as it is.

Cheers

Thanks @Tommy

Regards Zeus

If you implement onCreateDialog to use AlertDialog, you will bump into IllegalStateException: Fragment does not have a view when accessing getChildFragmentManager or something equivalent.

To solve this issue, implement both onCreateDialog and onCreateView, where onCreateView return the view inflated in onCreateDialog.

class LocationPickerDialog : DialogFragment() {

    lateinit var customView: View

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return customView
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        Log.d(TAG, "onCreateDialog")
        // StackOverflowError
        // customView = layoutInflater.inflate(R.layout.dialog_location_picker, null)
        customView = activity!!.layoutInflater.inflate(R.layout.dialog_location_picker, null)

        val builder = AlertDialog.Builder(context!!)
                .setView(customView)
                .setPositiveButton(android.R.string.ok) { _, _ ->
                    // do something
                }
                .setNegativeButton(android.R.string.cancel) { _, _ ->
                    // do something
                }
        val dialog = builder.create()

        return dialog
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        // if onCreateView doesn't return a view 
        // java.lang.IllegalStateException: Fragment does not have a view
        mapFragment = childFragmentManager.findFragmentByTag("map") as SupportMapFragment?
    }
}

https://code.luasoftware.com/tutorials/android/android-alertdialog-in-dialogfragment-fragment-does-not-have-a-view/