5

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();

実際のソリューションは今でも高く評価されています。

4

1 に答える 1

3

私自身は使用したことがありませんが、FragmentManager.executePendingTransactions()を見たことがありますか? ドキュメントの内容は次のとおりです。

FragmentTransaction が FragmentTransaction.commit() でコミットされた後、プロセスのメイン スレッドで非同期に実行されるようにスケジュールされます。このような保留中の操作をすぐに実行したい場合は、この関数を (メイン スレッドからのみ) 呼び出すことができます。すべてのコールバックとその他の関連する動作はこの呼び出し内から行われることに注意してください。そのため、これがどこから呼び出されるかについて注意してください。

ユースケースに合っているようです。

于 2014-11-20T15:06:03.333 に答える