我一直在努力找到在含有 ViewPager 的 FragmentActivity 中正确管理 Fragment 的方法。在详细说明问题之前,以下是我面临的问题的简要概述:
我有一个带有 ViewPager 的 FragmentActivity。ViewPager 使用一个自定义但非常简单的 FragmentPagerAdapter。ViewPager 中的每个 Fragment 都包含一个 ExpandableListView。我还有一个名为“Refresh”的操作栏按钮。现在,让我们假设 ViewPager 只有一个 Fragment。创建了活动,并填充了 Fragment 的 ExpandableListView(到目前为止都很好)。当点击刷新按钮时,FragmentActivity 中的处理方法会迭代分配给 FragmentPagerAdapter 的 Fragment 列表,并对每个 Fragment 调用 refresh() 以填充其 ListView。然而,当设备的方向发生变化(例如从纵向到横向),活动将被重新创建,Fragments 也将被重新创建。现在再次点击刷新按钮将迭代未初始化的 Fragments。
我知道我描述得很模糊,特别是没有示例代码。请耐心等待。我从应用程序/活动的开始一直跟踪问题和方法调用如下:
1. FragmentActivity.onCreate() 2. FragmentActivity.setContentView() 3. FragmentActivity.createPagerFragments() <-- 这将创建一个 Fragment 列表,并将它们分配给新的 FragmentPagerAdapter,该适配器又分配给 ViewPager。 4. Fragment.onAttach() 5. Fragment.onCreate() <-- 在这里没有什么特别之处,只是调用父方法。 6. Fragment.onCreateView() <-- 这里也没有什么特别之处,只是膨胀布局 7. Fragment.onActivityCreated() <-- 这里也没有任何东西。 8. <<一切正常,在这里更改方向>> 9. FragmentActivity.onCreate() 10. Fragment.onAttach() 11. Fragment.onCreate() 12. FragmentActivity.setContentView() 13. FragmentActivity.createPagerFragments() 14. Fragment.onCreateView() 15. Fragment.onActivityCreated() 16. <<点击刷新按钮>> 17. FragmentActivity.refresh() <-- 迭代从 #13 创建的新 Fragments(不是 Android!)。 18. <<崩溃:Fragment 中的 mExpandableListView 为空指针异常。>> 因此,我认为问题如下:当 Android 在屏幕方向更改后重新创建 FragmentActivity 及其 Views(调用上述 #9-15)时,它会创建具有其状态恢复为原始状态的新 Fragment 对象。但是,这些对象似乎完全由 FragmentManager 管理,而不是由 FragmentPagerAdapter 管理。相反,当 FragmentPagerAdapter 在活动的 onCreate 方法中与 Fragments 一起重新创建时(请参见调用#13),分配给适配器的 Fragments 没有调用它们的 Fragment.onCreate() 或 Fragment.onCreateView() 方法。所以当调用 refresh() 方法(请参见#17)时,该方法迭代这些未初始化的 Fragments。因此,当它们尝试填充 ExpandableListView 时,视图的实例变量为 NULL。预期这样,因为实例变量仅在未调用这些 Fragments 的 Fragment.onCreateView() 方法中分配。
因此,我的问题是:如何正确地重复使用屏幕方向更改后由 Android 重新创建的 Fragments,以避免创建不初始化的新 Fragments?我需要对它们有有效的引用,以调用它们的 refresh() 方法以按需填充它们。最理想情况下,它们还应分配给 FragmentPagerAdapter。
我希望我已经清楚地描述了问题,之所以没有提供示例代码的原因是,问题并不在于代码本身,而是因为错误的(看起来是)重新创建 Fragments 而不是重复使用。但是,如果需要,我可以提供示例代码,我只是认为这种方式会更清晰。谢谢!
我有一个带有 ViewPager 的 FragmentActivity。ViewPager 使用一个自定义但非常简单的 FragmentPagerAdapter。ViewPager 中的每个 Fragment 都包含一个 ExpandableListView。我还有一个名为“Refresh”的操作栏按钮。现在,让我们假设 ViewPager 只有一个 Fragment。创建了活动,并填充了 Fragment 的 ExpandableListView(到目前为止都很好)。当点击刷新按钮时,FragmentActivity 中的处理方法会迭代分配给 FragmentPagerAdapter 的 Fragment 列表,并对每个 Fragment 调用 refresh() 以填充其 ListView。然而,当设备的方向发生变化(例如从纵向到横向),活动将被重新创建,Fragments 也将被重新创建。现在再次点击刷新按钮将迭代未初始化的 Fragments。
我知道我描述得很模糊,特别是没有示例代码。请耐心等待。我从应用程序/活动的开始一直跟踪问题和方法调用如下:
1. FragmentActivity.onCreate() 2. FragmentActivity.setContentView() 3. FragmentActivity.createPagerFragments() <-- 这将创建一个 Fragment 列表,并将它们分配给新的 FragmentPagerAdapter,该适配器又分配给 ViewPager。 4. Fragment.onAttach() 5. Fragment.onCreate() <-- 在这里没有什么特别之处,只是调用父方法。 6. Fragment.onCreateView() <-- 这里也没有什么特别之处,只是膨胀布局 7. Fragment.onActivityCreated() <-- 这里也没有任何东西。 8. <<一切正常,在这里更改方向>> 9. FragmentActivity.onCreate() 10. Fragment.onAttach() 11. Fragment.onCreate() 12. FragmentActivity.setContentView() 13. FragmentActivity.createPagerFragments() 14. Fragment.onCreateView() 15. Fragment.onActivityCreated() 16. <<点击刷新按钮>> 17. FragmentActivity.refresh() <-- 迭代从 #13 创建的新 Fragments(不是 Android!)。 18. <<崩溃:Fragment 中的 mExpandableListView 为空指针异常。>> 因此,我认为问题如下:当 Android 在屏幕方向更改后重新创建 FragmentActivity 及其 Views(调用上述 #9-15)时,它会创建具有其状态恢复为原始状态的新 Fragment 对象。但是,这些对象似乎完全由 FragmentManager 管理,而不是由 FragmentPagerAdapter 管理。相反,当 FragmentPagerAdapter 在活动的 onCreate 方法中与 Fragments 一起重新创建时(请参见调用#13),分配给适配器的 Fragments 没有调用它们的 Fragment.onCreate() 或 Fragment.onCreateView() 方法。所以当调用 refresh() 方法(请参见#17)时,该方法迭代这些未初始化的 Fragments。因此,当它们尝试填充 ExpandableListView 时,视图的实例变量为 NULL。预期这样,因为实例变量仅在未调用这些 Fragments 的 Fragment.onCreateView() 方法中分配。
因此,我的问题是:如何正确地重复使用屏幕方向更改后由 Android 重新创建的 Fragments,以避免创建不初始化的新 Fragments?我需要对它们有有效的引用,以调用它们的 refresh() 方法以按需填充它们。最理想情况下,它们还应分配给 FragmentPagerAdapter。
我希望我已经清楚地描述了问题,之所以没有提供示例代码的原因是,问题并不在于代码本身,而是因为错误的(看起来是)重新创建 Fragments 而不是重复使用。但是,如果需要,我可以提供示例代码,我只是认为这种方式会更清晰。谢谢!