ViewPager,其中一个页面包含多个片段"java.lang.IllegalArgumentException:找不到id的视图"

Mat*_*ieu 16 android android-layout android-fragments android-viewpager

在我的小型Android应用程序中,我有一个ViewPager3页,每个页面包含一个片段,这一切都正常FragmentStatePagerAdapter(见前面的问题).

现在对于更大的屏幕,我想保留一个ViewPager,但我希望前两个片段在同一个第一页上.

为此,我实现了我自己的PagerAdapter,这主要是工作,我试图解决的唯一问题是当我旋转屏幕时,我收到一个错误:

12-11 16:34:13.526: ERROR/AndroidRuntime(9221): FATAL EXCEPTION: main
        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.matthieu/com.matthieu.TestActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f030002 (com.matthieu:id/top_fragment) for fragment TestFragment{481a3a98 #0 id=0x7f030002}
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3815)
        at android.app.ActivityThread.access$2400(ActivityThread.java:125)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:123)
        at android.app.ActivityThread.main(ActivityThread.java:4627)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:521)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
        at dalvik.system.NativeStart.main(Native Method)
        Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f030002 (com.matthieu:id/top_fragment) for fragment TestFragment{481a3a98 #0 id=0x7f030002}
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:903)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1861)
        at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129)
        at android.app.Activity.performStart(Activity.java:3781)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2636)
        ... 12 more
Run Code Online (Sandbox Code Playgroud)

我在GitHub上放了一个示例代码,模拟我要做的事情(并显示此错误消息).

我想我遇到的一个问题是因为我在实际应用程序中有碎片,我实际上不能有一个static newInstance构造函数,而是提前创建了碎片并且有'setRetainInstance(true);' 组.

我理解viewGroup包含片段的id 应该是层次结构的一部分,最后,我想,它是......

如果它有任何区别,我使用支持库和SherlockActionBar来保持与旧设备的向后兼容性.

关于如何解决这个问题的任何想法?

编辑:我发现,如果我从删除片段FragmentManageronSaveInstanceState,我没有得到任何崩溃了.所有的片段都是从头开始重新创建的,这不是我想要的,但我想我可能不得不这样做,并以某种方式稍后恢复这些片段....

Mat*_*ieu 18

好吧,即使我转向另一种做事方式,我也不喜欢让事情不完整......

按照马克的建议,继续使用嵌套的碎片.注释中发布的链接转到404,但我找到了关于嵌套片段的示例代码.

我在途中学到的一些东西:

  • 嵌套片段不能拥有setRetainInstance(true),或者它将获得:

    java.lang.IllegalStateException:无法保留嵌套在其他片段中的fragements

  • FrameLayoutViewPager保存片段的页面中创建一个是错误的.查看Android代码(特别是FragmentPagerAdapter),我应该用它container.getId()来找到添加的位置Fragment.看起来你不能在那个级别做任何更复杂的事情,否则它会破裂.

  • 根据我的理解,如果片段包含一些需要很长时间加载的信息(就像我一样),处理这个的不同方法是:

    • 使用onSaveInstanceState(首选方式?),但如果片段嵌套则不可能.当框架需要时,将调用(空)构造函数.
    • 使用setRetainInstance(true),在这种情况下savedInstanceBundle始终null,但片段(如Java对象)都不会被破坏,它仍然会经历onAttach/onCreateView.
    • 找到一些其他方法来保存和恢复你需要的东西......

无论如何,我在github上使用嵌套片段推送了我的解决方案

  • +1"嵌套片段不能有setRetainInstance(true)" (3认同)