2

简短版本:我想知道当该片段包含对无法序列化或复制且需要保留在内存中的对象的引用时,我如何重新创建片段状态(例如,在屏幕旋转之后)。

长版: 在我的应用程序中,我使用连接到自定义FragmentPagerAdapter的ViewPager ,该自定义 FragmentPagerAdapter实例化了许多显示包含在 ListView 中的数据(计划)的片段。所有这些都包含在父片段中。当由适配器实例化时,每个页面片段都被传递一个对一个对象(“ ScheduleManager ”)的引用,该对象执行以下几项操作:

  • 包含要显示的数据
  • 持有对Context对象的引用(为了访问SharedPreferences
  • 持有对父片段LoaderManager的引用,以便它可以重新加载数据
  • 实现OnClick - 和ActionMode回调侦听器(能够创建和处理适用于所有页面的操作模式;页面片段将对象作为侦听器添加到其 ListViews)
  • 定义一个回调接口来通知监听器状态变化或数据何时重新加载(页面片段将自己注册为监听器)。

本质上,ScheduleManager将所有东西放在一起,并实现了我的应用程序的这个(“调度”)部分的主要逻辑,即加载和提供数据,以及通过ActionMode修改和重新加载它的方法。不知道这个设计好不好...

我的问题是在这些情况下我应该如何恢复 Fragments 实例状态?我无法将ScheduleManager序列化为一个包,因为它会丢失对 Context 和LoaderManager的引用(当然,我会使用setArguments / getArguments)。此外,所有页面片段都必须引用同一个ScheduleManager实例,否则共享操作模式将不起作用。除此之外,我不想在每次恢复片段时都复制整个计划数据。我想将此对象保留在内存中,并让页面片段在恢复时回收对它的引用。

我想我可以让包含的活动持有ScheduleManager并让PageFragment查询它以获取参考。但如果可能的话,我更愿意将父片段中的所有内容保持为独立和模块化(不同的项目可以有不同的时间表)。在写这篇文章的时候,虽然我觉得没有办法解决这个问题。

当然,在重新创建父片段时,它也可以重新创建ScheduleManager并向其提供所需的引用(Context + LoaderManager)。问题是每个父fragment的实例不能有超过一个ScheduleManager的实例,那么如何让嵌套的页面fragment重新连接到它。

4

1 回答 1

1

这是我最终做的事情:

public void onCreate(Bundle savedInstanceState)
{
    Fragment fragment = this.getActivity().getFragmentManager().findFragmentByTag("SCHEDULE");
    if (fragment instanceof ScheduleMasterFragment)
    {
        ScheduleMasterFragment master = (ScheduleMasterFragment) fragment;
        this.scheduleManager = master.getScheduleManager();
    }
    else
    {
        throw new RuntimeException("SchedulePageFragment must be " +
                "the child of a ScheduleMasterFragment with Tag set to 'schedule'");
    }
    super.onCreate(savedInstanceState);
}

ScheduleManager 是我想保留的参考。至少通过这种方式,我将所有代码都保留在片段本身中,除了getScheduleManagerScheduleMasterFragment有意义,因为ScheduleMasterFragment不知何故是 ScheduleManager 实例的所有者。

仍然欢迎任何更好的解决方案...

于 2013-02-07T00:59:19.763 回答