10

私は非常に大きな問題を抱えており、何が起こっているのかかなり分かりません。私は(サポートライブラリからの)Fragmentsを使用するアプリケーションを開発しており、FragmentTransaction.replace()を使用して新しいフラグメントをバックスタックに置き、古いものを置き換えています。コードは次のようになります。FragmentTransaction.replace()を使用した場合のAndroid Fragmentビューの状態の損失

FragmentManager fm = getSupportFragmentManager(); 
FragmentTransaction ft = ft.beginTransaction(); 
// Animations in my res/anim folder 
ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right); 
ft.replace(R.id.fragment_container, newFragment, tag); 
ft.addToBackStack(null); 
ft.commit(); 

これは、私の断片を置き換えるのに成功しています。私の問題は次のとおりです。 1つのフラグメントでは、ユーザー入力から作成されたアイテムのリストがあります。次に、ユーザーが次へをクリックして戻るボタンをクリックすると(リストに戻る)、ビューは破棄されるため、リストは空になります。今、私は次のことに気付いた:

  1. onSaveInstanceStateが呼び出されていない。これは、親アクティビティーが指示するときにのみ呼び出されるからです。ドキュメントに基づいて: "(UIが表示されていないバックスタックに置かれたときのように)フラグメントが大部分が分解される可能性がある多くの状況がありますが、その所有アクティビティが実際にその状態を保存する必要がある"。どうやら、FragmentTransactionでの置換の実行はその時代の一つではありません。誰かがこれまたはより良い説明を確認していますか?
  2. この状況では、setOnRetainInstanceState(true)は役に立ちません。ここでも、私はこれがドキュメントの情報と関係していると考えています。「フラグメントインスタンスがアクティビティの再作成(コンフィグレーションの変更など)全体で保持されるかどうかを制御する」私はアクティビティを再作成する際に何もしませんので、これは役に立たないものです。

私の主な質問は、replaceを使用している場合、ビューステート(単にフラグメントを保持する)を保持する方法があるのでしょうか? FragmentTransaction.add()がありますが、これにもいくつかの問題があります。 1つは終了アニメーションが実行されないため、アニメーションが正しくありません。もう1つは、古いフラグメント(非可視状態にされているフラグメント)がまだクリック可能であるという新しいフラグメントです。例えば、私がListFragmentを持っていて、addを使ってその上にコンテンツフラグメントを置くと、ListFragment内のリストアイテムをクリックすることができます。

答えて

2

フラグメントのコードを見ることはできませんが、これは少し推測ですが、過去に私はこの同じ問題を抱えていましたが、ListFragmentのアダプタをリセットすると、onViewStateRestoredトリックを行う。ドキュメントを考慮奇妙です

public void onViewStateRestored (Bundle savedInstanceState) 
{ 
    super.onViewStateRestored (savedInstanceState); 
    setListAdapter(new ArrayAdapter(Activity, R.layout.nav_item, objects)); 
} 

は、この方法がonActivityCreated後でonStart前に呼び出されると述べています。しかし、最新のフラグメントトランザクションがバックスタックからポップされると、以前に置き換えられたフラグメントが表示される前に呼び出されるため、他のときに呼び出されるようです。フラグメントを所有するアクティビティは一時停止されておらず、またどのような方法でも隠されていないので、ドキュメントによってはonViewStateRestoredが呼び出されるべきではありません。しかし、これはとにかく動作するようです。

2

onCreateViewとonDestroyViewが正しく実装されているかどうかを確認する必要があるようです。あなたが記述している状況は、リストフラグメントが(トランザクションの置換の結果として)バックスタックに置かれたときに、Androidがいくつかのリソースを解放するためにonDestroyViewを呼び出していることを示しているようです。しかし、それは明らかにリストフラグメントを破壊していないと思います。なぜなら、あなたがタップバックするとフラグメントの同じインスタンスが戻ってくるからです。

これが真であると仮定すると、ユーザーがAndroidをタップするとonCreateViewが呼び出されます。フラグメントのインスタンス変数に格納されている状態は、そこに残っていて、必要なのはビューの再作成だけです。おそらく、ListViewなどのアダプタを設定します。

また、onSaveInstanceState()コールバックが実際にビューを再構築するために必要なインスタンス状態を保存していることを確認してください。そうすれば、フラグメントが実際に完全に破壊された場合、FragmentManagerは後でフラグメントを再作成する必要があるときに状態を復元できます。

関連する問題