DialogFragment中的ViewPager – IllegalStateException:Fragment没有视图

我想实现的

  • FragmentActivity ,单击Action Bar中的Action Button时会显示一个对话框
  • DialogFragment – 一个没有标题的对话框
  • TabHost – 对话框顶部的标签
  • 带有FragmentPagerAdapter ViewPager – Swipable,其内容连接到Tabs
  • 2-3个对话框button(对话框的不同子类,不同的button) – 不应该在ViewPagerFragment ,这意味着相同的button应该保留在对话框的底部,而不pipeViewPager Fragment显示的是什么。

问题

 IllegalStateException: Fragment does not have a view 

到目前为止,我已经尝试了/做了什么

  • 使用android.support.v4包进行必要的类
  • 调用getChildFragmentManager()而不是getSupportedFragmentManager()
  • 从此链接https://code.google.com/p/android/issues/detail?id=42601实施了#10build议的内容。 我将代码直接复制/粘贴到ViewPager假设要显示的两个Fragment类中,再加上DialogFragment类。
  • 在我的自定义DialogFragment我首先尝试重写onCreateView ,然后onCreateDialog ,然后在两个同时。 所有我运行,但意想不到的结果。
    • 只有onCreateView :无法到达AlertDialog.Builder创build所需的button,除了该对话框的结果是伟大的。
    • 只有onCreateDialog :上面显示的错误信息。 我仍然认为这种方法和我想要达到的一样接近。
    • onCreateViewonCreateDialog :在onCreateView AlertDialog.Builder对话框布局,并将对话button添加到onCreateDialogAlertDialog.Builder 。 这显示了对话框,但从AlertDialog.Builder添加的button不可见。 另外,点击EditText字段时键盘没有显示出来。

源代码

大部分来自教程来实现在Android 2.2 + ViewPager和Fragments中使用TabHostActivityFragment的代码是在一个DialogFragment 。 不过,我从这个答案https://stackoverflow.com/a/18167273/2375978源代码更换了它的ViewPager。 这是能够在高度wrap_content

我的项目错误的代码是在DialogFragmentonCreateDialog方法,我相信。

 @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; } 

堆栈跟踪LogCat日志

 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 

也…

  • 我没有成功地尝试https://code.google.com/p/android/issues/detail?id=42601中提到的其他可能的解决scheme(在第2和第13个post中提到),因为我没有理解如何以及在哪里可以在我的代码中使用它(我想我和编写#18的人在同一条船上)。

Solutions Collecting From Web of "DialogFragment中的ViewPager – IllegalStateException:Fragment没有视图"

我想我只是遇到了同样的问题,并通过查看DialogFragment的源代码学到了一些东西。

它看起来像即使重写onCreateDialog(…)是创build自定义对话框的有效方法,它将导致DialogFragment具有空视图,就像错误消息所述。 在大多数情况下,这是好的 – DialogFragment不需要一个视图来显示一个对话框,但是如果你想进一步嵌套片段(就像你一样),这将不会飞。

考虑到你想与AlertDialog.Builder进行交互,我没有看到完美的解决scheme,但是你有几个select:

  1. 在对话框中创build按​​钮作为视图的一部分(不使用AlertDialog.Builder)。 你通过覆盖onCreateView 而不是 onCreateDialog 做到这一点。 您应该能够通过将button放在自己的片段中来获得您提到的function。 我们在演出中做类似的事情,我非常喜欢这种方法。
  2. 实现你自己的从Fragmentinheritance而来的types,除了允许你需要的东西以外,它以各种方式镜像DialogFragment。 DialogFragment只有〜400,这不应该太吓人,而且会受到很多的评论。 可以很有趣。
  3. 使用常规PagerAdapter而不是FragmentPagerAdapter。 这样,你的DialogFragment没有View就没关系了。

使用

 onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 

而不是onCreateDialog(Bundle savedInstanceState)。 不要创build一个警告对话框,使用方法提供的inflater,并build立你的看法。 这个对我有用。

最好的祝福!

感谢@Tommy Visic写了一个非常好的描述,它的工作。

发布为我工作的代码。

我已经从onCreateDialog方法中删除了Dialog构build代码,实际上删除了onCreateDialog方法和我已经在Dialog's自定义视图中实现的对话框视图,我已经在onCreateView方法中包含它作为一个View ,所有的东西开始工作。

 @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; } 

面对一个更多的问题,这个实现是:

当一个Activity具有Toolbar/ActionBar它也会显示在DialogFragment以避免这样做:实现Fragment onViewCreated方法并添加下面的代码

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

这将从DialogFragment删除ToolbarActivity将按DialogFragment显示。

干杯

谢谢@Tommy

问候宙斯