7

sを使用したタブ付きアプリケーションFragmentと、わずかな問題があります。

MainActivity(extends FragmentActivity- with no code save for the layout specification on onCreate) は、Fragment呼び出されたTabsFragment(extends Fragment, implements OnTabChangeListener) をそのレイアウト (タブ自体を a に格納) に含め、 s を使用FrameLayoutしてサブを切り替えます。FragmentTransaction

後者のサブFragmentsは、ユーザーがデバイスの電源を入れたとき、別のアプリケーションにアクセスしたとき、電話に応答したとき、または何か他のことをしたときに状態を保存したい実際のコンテンツを含むものです。現在、サブFragmentの状態は保存されていませんが、アクティビティはどのサブFragmentが表示されているかを記憶しています。(したがって、デバイスを横向きモードにして、タブ 3 がアクティブなときにデバイスを回転させると、タブ 3 が縦向きモードで表示され、リセットされますが、表示されます。そのため、何もしなくても状態が保持されます)。

私は複数のレイアウト (横向きと縦向き) を持っているのでandroid:configChanges="orientation"、マニフェストではオプションではありません。

私は v4 サポート ライブラリ (rev 10) を使用しており、API を精査した後FragmentManager.saveFragmentInstanceState()Fragment.setInitialSavedState(Fragment f). FragmentのオーバーライドされたonPause()メソッドの各サブに saveFragmentInstanceState() を配置しましたTabsFragment。をどこに置いても - が表示setInitialSavedStateされるため、これが機能するかどうかはわかりませんIllegalStateExceptionが、これは新しいサブタブを初期化したばかりの場合でも発生しFragmentます。に入れるとクラッシュonResumeTabsFragmentます。

コードスニペット:

//... this is the 'showTab' method
if(getFragmentManager().findFragmentByTag(id) == null)
{
  Fragment f = null;
  if(BASIC_TAB.equals(id))
  {
    f = new BasicTabFragment();
    f.setInitialSavedState(basicState); // basicState was set in onPause()
    getFragmentManager().beginTransaction().replace(tabNo, f, tabID).commit();
  }
}

に同様のコードを配置するとonResume、次のエラーが発生します。

エラー スニペット: FATAL EXCEPTION: main java.lang.RuntimeException: Unable to resume activity (org.example.App/org.example.App/MainActivity): java.lang.IllegalStateException: Fragment already active

-snip-

Caused by: java.lang.IllegalStateException: Fragment already active at  android.support.v4.app.Fragment.setIniailSavedState(Fragment.java:507)
at org.example.App.TabsFragment.onResume(TabsFragment.java:223)

ライフサイクルの間違った時点で setInitialSavedState を呼び出していることは明らかですが、これがいつ発生するかは明確ではありません。

また、タブ付きセットアップのやや複雑な性質を考えると、FragmentManager.saveFragmentInstanceState() が実際にここで使用するのに最適なものであるかどうか疑問に思い始めています。もしそうなら、何を使うべきですか?アプリケーションのタブの状態を保存するにはどうすればよいですか?

4

1 に答える 1

2

アクティビティが破棄されると、フラグメントはアクティビティから切り離され、再作成されるときに再接続されます。したがって、フラグメントは現在の状態でまだ存在している必要があります。再接続すると、OnCreateView再度呼び出されます。すべてをゼロから初期化する (つまり、リストを に設定するnew ArrayList()) 場合は、フラグメントの状態を一掃することになります。

保持する必要があるすべてのものについて、フラグメント内にインスタンス変数を作成してみてください(つまり、テキストフィールドの文字列-言及したように、EditTextフィールドは自動的に保存されます)。例:

文字列テキスト。
TextView テレビ;

public View onCreateView(LayoutInflater i, ViewGroup vg, Bundle b)
{
   // これにより、レイアウトからすべてが再膨張します。ここでテキスト フィールドを初期化すると、xml ファイルで設定した値にリセットされます。
   View v = i.inflate(R.layout.myLayout, vg, false);

   if(テキスト != null)
       tv.setText(テキスト);
}

TextView の値が変更されたら (OnClickListener などで)、その他の操作textに加えての値を設定します。フラグメントが再アタッチされると、最後に行われた変更に設定されます。

于 2013-01-04T09:53:24.577 に答える