ViewPager in DialogFragment - IllegalStateException: Fragment does not have a view
android, android-dialogfragment, android-fragments, android-viewpager
Solution
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:
- 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.
- 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.
- Use a regular PagerAdapter instead of a FragmentPagerAdapter. This way it won't matter that your DialogFragment doesn't have a View.
Problem
What I want to achieve - From a `FragmentActivity` show a dialog when clicking an Action Button in the Action Bar - `DialogFragment` - A Dialog without title - `TabHost` - Tabs at the top of the dialog - `ViewPager` with `FragmentPagerAdapter` - Swipable, which content is connected to the Tabs - 2-3 Dialog Buttons (different subclasses of the Dialog, different buttons) - Are not supposed to be in one of the `ViewPager`'s `Fragment`, meaning the same buttons should remain at the bottom of the Dialog regardless of what `Fragment` the `ViewPager` is showing. The problem ``` IllegalStateException: Fragment does not have a view ``` What I have tried/done so far - Using the `android.support.v4` package for necessary classes - Calling `getChildFragmentManager()` instead of `getSupportedFragmentManager()` - Implemented what post #10 suggested from this link https://code.google.com/p/android/issues/detail?id=42601. I copy/paste the code directly into my two `Fragment` classes, which the `ViewPager` is suppose to be showing, plus the `DialogFragment` class. - In my custom `DialogFragment` I first tried to override `onCreateView`, then `onCreateDialog` and then both at the same time. All of which I got to run but with unexpected results. - Only `onCreateView`: Can't reach the `AlertDialog.Builder` to create the needed buttons, other than that the Dialog's results were great. - Only `onCreateDialog`: the error message shown above. I still imagine this method to be as close as I've gotten to what I want to achieve. - Both `onCreateView` and `onCreateDialog`: Inflated the Dialog layout in `onCreateView` and added the Dialog buttons to the `AlertDialog.Builder` in `onCreateDialog`. This displayed the dialog, but the added buttons from the `AlertDialog.Builder` were not visable. Plus the keyboard didn't show up when clicking on a `EditText` field. Source code Most come from Tutorial to implement the use of TabHost in Android 2.2 + ViewPager and Fragments. The code of the `ActivityFragment` is instead in a `DialogFragment`. However I replaced its ViewPager with a modified one from the source code from this answer https://stackoverflow.com/a/18167273/2375978. This was to be able to `wrap_content` on height. The faulty code in my project is in `DialogFragment`'s `onCreateDialog` method, I believe. ``` @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), AlertDialog.THEME_HOLO_DARK); LayoutInflater inflater = getActivity().getLayoutInflater(); view = inflater.inflate(R.layout.dialog_test, null); addActionButtons(builder, view); builder.setView(view); mViewPager = (WrapContentHeightViewPager) view.findViewById(R.id.viewpager); initialiseTabHost(); List<Fragment> fragments = getFragments(); pageAdapter = new DialogPageAdapter(getChildFragmentManager(), fragments); mViewPager.setAdapter(pageAdapter); mViewPager.setOnPageChangeListener(this); Dialog dialog = builder.create(); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); dialog.show(); return dialog; } ``` Stack trace LogCat log ``` FATAL EXCEPTION: main java.lang.IllegalStateException: Fragment does not have a view at android.support.v4.app.Fragment$1.findViewById(Fragment.java:1425) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:901) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444) at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:461) at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141) at android.support.v4.view.ViewPager.populate(ViewPager.java:1011) at android.support.v4.view.ViewPager.populate(ViewPager.java:880) at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1374) at my.app.package.name.WrapContentHeightViewPager.onMeasure(WrapContentHeightViewPager.java:31) at android.view.View.measure(View.java:15481) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5059) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1396) at android.widget.LinearLayout.measureVertical(LinearLayout.java:681) at android.widget.LinearLayout.onMeasure(LinearLayout.java:574) at android.view.View.measure(View.java:15481) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5059) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.view.View.measure(View.java:15481) at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:617) at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:399) at android.view.View.measure(View.java:15481) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5059) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.view.View.measure(View.java:15481) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5059) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.view.View.measure(View.java:15481) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5059) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1396) at android.widget.LinearLayout.measureVertical(LinearLayout.java:681) at android.widget.LinearLayout.onMeasure(LinearLayout.java:574) at android.view.View.measure(View.java:15481) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5059) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.view.View.measure(View.java:15481) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5059) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.view.View.measure(View.java:15481) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5059) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2377) at android.view.View.measure(View.java:15481) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1982) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1200) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1398) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1118) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4525) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) at android.view.Choreographer.doCallbacks(Choreographer.java:555) at android.view.Choreographer.doFrame(Choreographer.java:525) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4946) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.jav ``` Also... - I have unsuccessfully been able to try the other possible solution mentioned in https://code.google.com/p/android/issues/detail?id=42601, mentioned in post #2 and #13, because I haven't understood how and where I can use it in my code (I guess I'm in the same boat as the person who wrote #18).