FragmentStatePagerAdapter
上記のタイトルはよく聞かれますが、答えは私の問題とは関係のないものと密接に関係しているようです。メソッドputFragment(Bundle, String, Fragment)
を直接使用しています。
のAndroidドキュメントにputFragment(Bundle, String, Fragment)
は次のように書かれています:
Put a reference to a fragment in a Bundle. This Bundle can be persisted as saved state, and when later restoring getFragment(Bundle, String) will return the current instance of the same fragment.
Parameters
* bundle The bundle in which to put the fragment reference.
* key The name of the entry in the bundle.
* fragment The Fragment whose reference is to be stored.
ただし、次のコードは例外をスローします。
Bundle bundle = new Bundle();
CustomFragment actionBarFragment = getActionBarFragment();
CustomFragment contentFragment = getContentFragment();
actionBarFragment.setArguments(bundle);
contentFragment.setArguments(bundle);
FragmentTransaction mTransaction = getSupportFragmentManager().beginTransaction();
mTransaction.add(R.id.actionBarPane, actionBarFragment);
mTransaction.add(R.id.contentPane, contentFragment);
mTransaction.commit();
getSupportFragmentManager().putFragment(bundle, "ContentFragment", contentFragment);
getSupportFragmentManager().putFragment(bundle, "ActionBar", actionBarFragment);
上記を使用している理由は、ContentFragment と ActionBar フラグメントの両方が、getArguments()
現在バックスタックの一番上になくても、結果を使用して反対の番号を見つけることができるようにするためです。たとえば、透過によって部分的に遮られている場合などです。スタックの上位にあるフラグメント。
ただし、例外が発生します。
11-20 13:44:17.842: E/Default Exception Handler(12466): Caused by: java.lang.IllegalStateException: Fragment CustomFragment{4219bdb8 id=0x7f06002e com.test.CustomFragment1} is not currently in the FragmentManager
commit()
このことから、UI スレッドで実行されるようにトランザクションをスタックに置くだけで、putFragment()
そのトランザクションが実行される前に呼び出しが行われていると結論付けることができますか? それとも私は何かを誤解していますか?(Android サイトのドキュメントには、フラグメントが本来あるべき状態であると想定するための前提条件の状態については何も記載されていません)。
commit()
呼び出しが早すぎると思われる理由のテキストに注目する価値があります。考えられる答えは、リスナーをトランザクションにアタッチして、トランザクションが処理されたときに通知する方法ですcommit()
。私はそれが存在するとは思わない...
このトランザクションのコミットをスケジュールします。コミットはすぐには行われません。次回のスレッドの準備ができたときに実行されるように、メイン スレッドでの作業としてスケジュールされます。
編集
commit()
ひどい解決策を使用して、それが問題であることを確認しました:
mTransaction.commit();
new Thread() {
public void run() {
while(!contentFragment.isAdded()) {
try {
Thread.sleep(100);
} catch (Exception e) {}
}
getSupportFragmentManager().putFragment(bundle, "ContentFragment", contentFragment);
getSupportFragmentManager().putFragment(bundle, "ActionBar", actionBarFragment);
};
}.start();
実際のソリューションは今でも高く評価されています。