一页包含多个片段的 ViewPager “java.lang.IllegalArgumentException:找不到 id 的视图" [英] ViewPager with one page containing multiple Fragments "java.lang.IllegalArgumentException: No view found for id"

查看:18
本文介绍了一页包含多个片段的 ViewPager “java.lang.IllegalArgumentException:找不到 id 的视图"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的小型 Android 应用程序中,我有一个包含 3 个页面的 ViewPager,每个页面包含一个片段,使用 FragmentStatePagerAdapter 可以正常工作(请参阅 之前的问题).

In my small Android app, I have a ViewPager with 3 pages, each page contains one fragment, that's all working fine with a FragmentStatePagerAdapter (see earlier question).

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

Now for larger screens, I would like to keep a ViewPager, but I want the first two fragments to be on the same first page.

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

For this, I implement my own PagerAdapter and this is mostly working, the only problem I am trying to resolve is when I am rotating the screen, I get an error:

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

我在 GitHub.

我想我遇到的一个问题是由于我在实际应用程序中拥有的片段,我不能真正拥有 static newInstance 构造函数,而是提前创建片段并具有'setRetainInstance(真的);'设置.

I guess one problem I have is because of the Fragments I have in the real application, I cannot really have a static newInstance constructor, but instead the Fragments are created ahead of time and have 'setRetainInstance(true);' set.

我了解 viewGroup 的 ID,它将包含片段 应该是层次结构的一部分,最终,我猜,它是……

I understand the id of the viewGroup that will contain the fragment should be part of the hierarchy, and eventually, I guess, it is...

如果有什么不同,我将使用支持库和 SherlockActionBar 来保持与旧设备的向后兼容性.

If it makes any difference, I am using the support library and the SherlockActionBar to maintain backwards compatibility with older devices.

你知道怎么做吗?

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

EDIT: I have found that if I remove the Fragments from the FragmentManager in onSaveInstanceState I am not getting any crash anymore. All the fragments are recreated from scratch which is not what I want, but I guess I might have to do this and somehow recover those fragments later....

推荐答案

好吧,虽然我换了另一种做事方式,但我不喜欢留下不完整的东西......

All right, even though I moved to another way of doing things, I don't like to leave things incomplete...

按照 Mark 的建议采用嵌套 Fragments 的方式.评论中发布的链接转到 404,但我找到了您的 示例代码 关于嵌套片段.

Going the way of the nested Fragments as suggested by Mark. The link posted in the comments goes to 404, but I found your example code about nested fragments.

我在路上学到了一些东西:

A few things I've learned on the way:

  • 嵌套片段不能有setRetainInstance(true),否则会得到:

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

java.lang.IllegalStateException: Can't retain fragements that are nested in other fragments

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

It was a mistake to create a FrameLayout in the page of the ViewPager to hold the fragment. Looking in the Android code (and specifically the FragmentPagerAdapter), I should just use container.getId() to find where to add the Fragment. Looks like you cannot do anything more sophisticated at that level or it will break.

据我了解,如果片段包含一些需要很长时间才能加载的信息(就像我一样),则处理此问题的不同方法是:

From my understanding, if the fragments hold some information (like I do) that takes a long time to load, the different ways to handle this are:

  • 使用 onSaveInstanceState(首选方式?),但如果 Fragment 是嵌套的,则不可能.框架需要时会调用(空)构造函数.
  • 使用setRetainInstance(true),在那种情况下savedInstanceBundle总是null,但是那个Fragment(作为Java对象)不会被销毁它仍然会通过 onAttach/onCreateView.
  • 寻找其他方法来保存和恢复您需要的内容...
  • Use onSaveInstanceState (preferred way ?), but not possible if the Fragment is nested. The (empty) constructor will get called when needed by the framework.
  • Use setRetainInstance(true), in that case savedInstanceBundle is always null, but that Fragment (as Java object) will not be destroyed and it will still go through onAttach / onCreateView.
  • Find some other way to save and restore what you need...

无论如何,我使用嵌套片段在 github

Anyway, I pushed my solution using nested fragments on github

这篇关于一页包含多个片段的 ViewPager “java.lang.IllegalArgumentException:找不到 id 的视图"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆