2

短いバージョン:このフラグメントに、シリアル化または複製できず、メモリに保持する必要があるオブジェクトへの参照が含まれている場合に、フラグメントの状態を再作成する方法を知りたいです(たとえば、画面の回転後)。

長いバージョン: 私のアプリでは、カスタムFragmentPagerAdapterに接続されたViewPagerを使用して、ListViewに含まれるデータ(スケジュール)を表示する多数のフラグメントをインスタンス化します。これはすべて、親フラグメント内に含まれています。アダプタによってインスタンス化されると、各ページフラグメントには、いくつかのことを行う1つのオブジェクト(「ScheduleManager」)への参照が渡されます。

  • 表示するデータが含まれています
  • ( SharedPreferencesにアクセスするために)Contextオブジェクトへの参照を保持します
  • 親フラグメントLoaderManagerへの参照を保持して、データをリロードできるようにします
  • OnClick-およびActionModeコールバックリスナーを実装します(すべてのページで機能するアクションモードを作成および処理できるようにするため。ページフラグメントは、オブジェクトをリスナーとしてListViewに追加します)
  • 状態の変化またはデータがリロードされたときにリスナーに通知するためのコールバックインターフェイスを定義します(ページフラグメントはリスナーとして登録されます)。

基本的に、ScheduleManagerはすべてをまとめて保持し、アプリのこの(「スケジュール」)部分のメインロジック、つまりデータの読み込みと提供、およびActionModeを介してデータを変更および再ロードする手段を実装します。これがいいデザインかどうかわかりません...

私の質問は、これらの状況でフラグメントインスタンスの状態をどのように復元するのかということです。ScheduleManagerをバンドルにシリアル化することはできません。これは、ContextとLoaderManagerへの参照が失われるためです(それ以外の場合は、もちろんsetArguments / getArgumentsを使用します)。また、すべてのページフラグメントには、 ScheduleManagerの同じインスタンスへの参照が必要です。そうでない場合、共有アクションモードは機能しません。それを除けば、フラグメントが復元されるたびにスケジュールデータ全体を複製したくありません。このオブジェクトをメモリに保持し、ページフラグメントが復元されたときにそのオブジェクトへの参照を再利用できるようにします。

含まれているアクティビティにScheduleManagerを保持させ、 PageFragmentに参照用にクエリを実行させることができると思います。ただし、可能であれば、親フラグメント内のすべてを自己完結型でモジュール式に保つことをお勧めします(アイテムごとに異なるスケジュールが存在する可能性があります)。これを書いていると、どうしようもない気がしますが。

もちろん、親フラグメントが再作成されると、ScheduleManagerを再作成して、必要な参照(Context + LoaderManager)をフィードすることもできます。問題は、親フラグメントのインスタンスごとにScheduleManagerのインスタンスが1つしか存在できないため、ネストされたページフラグメントを再接続する方法です。

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は、私が保持したかった参照です。少なくともこの方法では、ScheduleManagerインスタンスの所有者であるために意味があるgetScheduleManager場合を除いて、すべてのコードをフラグメント自体の中に保持します。ScheduleMasterFragmentScheduleMasterFragment

より良い解決策はまだ歓迎されています...

于 2013-02-07T00:59:19.763 に答える