3

特定の時間に複数 (2) のフラグメントを持つ単一のアクティビティを実行するアプリケーションがあります。左側にフラグメントがあり、右側に表示するフラグメントのメニューとして機能します。

例として、メニューがさまざまなスポーツで構成されているとしましょう。サッカー、バスケットボール、野球、スキーなど。ユーザーがスポーツを選択すると、特定のスポーツの詳細を含むフラグメントが右側に表示されます。

layout-large と layout-small-landscape で一度に 2 つのフラグメントを表示するようにアプリを設定しました。ただし、layout-small-portrait では、一度に表示されるフラグメントは 1 つだけです。

これを想像してみてください。ユーザーがレイアウト - スモール - ランドスケープ (一度に 2 つのフラグメント) でアプリをブラウジングし、スポーツのフットボールを選択します。彼がバスケットボールを選んだ直後。彼がレイアウト-スモール-ポートレート (一度に 1 つのフラグメント) に回転することを選択した場合、次のようにします。

Basketball フラグメントが表示されている必要がありますが、戻るボタンを押した場合、Football フラグメント (!) ではなく、メニューに戻る必要があります。これはデフォルトでバック スタックの前のフラグメントです。

私は現在、次のようにこれを解決しました:

....

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // static fragments
    if(menuFragment == null) menuFragment = new MenuFragment();
    if(baseFragment == null) baseFragment = new TimerFragment(); // default content fragment

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

    // Determine what layout we're in..
    if(app().getLayoutBehavior(this) == LayoutBehavior.SINGLE_FRAGMENT) {
    // We are currently in single fragment mode

        if(savedInstanceState != null) {

            if(!rotateFromSingleToDual) {
                // We just changed orientation from dual fragments to single fragment!

                // Clear the entire fragment back stack
                for(int i=0;i<getSupportFragmentManager().getBackStackEntryCount();i++) {
                    getSupportFragmentManager().popBackStack();
                }

                ft.replace(R.id.fragmentOne, menuFragment); // Add menu fragment at the bottom of the stack
                ft.replace(R.id.fragmentOne, baseFragment);
                ft.addToBackStack(null);
                ft.commit();
            }

            rotateFromSingleToDual = true;
            return;
        }

        rotateFromSingleToDual = true;

        ft.replace(R.id.fragmentOne, menuFragment);
    } else if(app().getLayoutBehavior(this) == LayoutBehavior.DUAL_FRAGMENTS) {
    // We are now in dual fragments mode

        if(savedInstanceState != null) {

            if(rotateFromSingleToDual) {
                // We just changed orientation from single fragment to dual fragments!
                ft.replace(R.id.fragmentOne, menuFragment);
                ft.replace(R.id.fragmentTwo, baseFragment);
                ft.commit();
            }

            rotateFromSingleToDual = false;
            return;
        }

        rotateFromSingleToDual = false;

        ft.replace(R.id.fragmentOne, menuFragment);
        ft.replace(R.id.fragmentTwo, baseFragment);
    }

    ft.commit();
}

これは、少なくとも時々機能します。ただし、何度も java.lang.IllegalStateException: Fragment already added: MenuFragment (....) を取得します。

これをより適切に実装する方法について、誰かが私にいくつかの指針を教えてください。私の現在のコードはまったくきれいではありません。多くの開発者がまさにこれを実現したいと考えています。

前もって感謝します!

4

1 に答える 1

2

このシナリオを実装する一般的な方法は、複数のフラグメントを表示するモードの場合にのみフラグメント スタックを使用することです。シングル フラグメント モードでは、単一のフラグメントを表示し、アクティビティ バック スタックを利用するだけの新しいアクティビティを開始します。

あなたの場合、新しいアクティビティを開始するときに引数として設定するために、回転時に現在選択されているスポットを覚えておく必要があります。

ここでよりよく説明されています:-

http://developer.android.com/guide/components/fragments.html

それが役立つことを願っています。

于 2013-01-23T22:26:39.050 に答える