web-dev-qa-db-ja.com

個々のフラグメントの手動で戻るボタンを押すと、前のフラグメントに戻る方法は?

アプリケーションにはactivityが1つとfragmentsが複数あります。

2つのメインフラグメントA(left) and B(right)。

Fragment A1 called from A

B1 called from B

B2 called from B1

すべてのfragmentsには個別の戻るボタンがあります。

fragmentA1の戻るボタンを押すと、[〜#〜] a [〜#〜]に戻るはずです。戻るボタンも同様ですfrom B2が押され、B1が表示され、from B1から[〜#〜] b [〜#〜]等々。

このタイプの機能を実装する方法は?

26
Mihir Shah
public void onBackPressed()
{
    FragmentManager fm = getActivity().getSupportFragmentManager();
    fm.popBackStack();
}
34
Manitoba

同様のシナリオを今実装しました。

アクティビティ「A」->フラグメント「A1」を呼び出してメニュー項目をクリックし、フラグメント「A2」を呼び出します。ユーザーが「A2」から戻るボタンを押すと、「A1」に戻り、ユーザーが押すとその後、「A1」から戻り、アクティビティ「A」を終了して戻ります。

次のコードを参照してください。

アクティビティ 'A'-OnCreate()メソッド:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activityA);

    if (savedInstanceState == null) {
        Fragment fragInstance;

        //Calling the Fragment newInstance Static method
        fragInstance = FragmentA1.newInstance();

        getFragmentManager().beginTransaction()
                .add(R.id.container, fragInstance)
                .commit();
    }
}

フラグメント: 'A1'

メニュー項目のクリックアクションが発生したときに、既存のフラグメントを新しいフラグメントに置き換えています。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.action_edit_columns) {
        //Open the Fragment A2 and add this to backstack
        Fragment fragment = FragmentA2.newInstance();
        this.getFragmentManager().beginTransaction()
                .replace(R.id.container, fragment)
                .addToBackStack(null)
                .commit();

        return true;
    }
    return super.onOptionsItemSelected(item);
}

アクティビティ 'A'-onBackPressed()メソッド:

すべてのフラグメントには1つの親アクティビティ(「A」)があるため、onBackPressed()メソッドを使用すると、フラグメントがある場合、または前のアクティビティに戻るだけでフラグメントをポップできます。

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 0) {
        super.onBackPressed();
    }
    else {
        getFragmentManager().popBackStack();
    }
}

フラグメント内にフラグメントを埋め込む場合は、リンクを参照してください: http://developer.Android.com/about/versions/Android-4.2.html#NestedFragments

23
TrueBlue

@trueblueの答えは、マイナーだが厄介な問題を1つ解決しました。バックスタックにフラグメントが1つしかない場合に[戻る]ボタンを押すと、そのフレームは削除され、アプリはアクティブなままで、空白の画面が表示されます。ユーザーがアプリを終了するには、もう一度戻るボタンを押す必要がありました。この状況を処理するために、元のコードを次のように変更しました

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 0) {
        super.onBackPressed();
    }
    else if(getFragmentManager().getBackStackEntryCount() == 1) {
        moveTaskToBack(false);
    }
    else {
        getFragmentManager().popBackStack();
    }
}

バックスタックにフラグメントが1つしかない場合、基本的にアプリ全体を後ろに移動するようにAndroidに伝えています。

更新(そしておそらくより良い答え)

このことについてさらに読んだ後、 フラグメントマネージャトランザクションをバックスタックに追加する で、その後Androidバックプレスを自動的に、望ましい方法で処理できることがわかりました。以下のコードスニペットは、その方法を示しています

Fragment fragment; //Create and instance of your fragment class here
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

fragmentTransaction.replace(R.id.fragment_container, fragment).addToBackStack(null);
fragmentTransaction.commit();
fragmentTransaction.addToBackStack(null);

最後の行は、トランザクションをバックスタックに追加する方法を示しています。これにより、1つを除くほとんどの状況でフラグメントのバックプレスの問題が解決されます。戻るボタンを押し続けると、最終的には、バックスタックにフラグメントが1つしかない時点に到達します。この時点で、次の2つのいずれかを実行できます。

  1. アクティビティが実行されているタスクのバックスタックからフラグメントを格納しているアクティビティを削除します。これは、空のアクティビティになりたくないためです。
  2. アクティビティがタスクのバックスタック内の唯一のアクティビティである場合、バックグラウンドでタスクをプッシュします。

私の場合、それは後者だったので、オーバーライドされたonBackPressedメソッドを以前の回答から以下のように変更しました

@Override
public void onBackPressed() {
    if(getFragmentManager().getBackStackEntryCount() == 1) {
        moveTaskToBack(false);
    }
    else {
        super.onBackPressed();
    }
}

このコードは、ロジックが少なく、カスタムコードよりもフレームワークに依存しているため、よりシンプルです。残念ながら、最初の状況ではコードを実装する必要がなかったため、どうにか実装できませんでした。

16
Suhas

ただやる

getActivity().getFragmentManager().popBackStack();
5
user4853635

説明したように、独自のバックスタック実装を実装する必要があります here。

フラグメントの[戻る]ボタンをクリックするたびにpopFragments()を呼び出し、フラグメント間を移動するたびにpushFragments()を呼び出すことができます。

4
TNR

これを試してみてください。

public void onBackPressed() {
    if (mainLayout.isMenuShown()) {
        mainLayout.toggleMenu();
    } else {
        FragmentManager fm = getSupportFragmentManager();
        Log.print("back stack entry", fm.getBackStackEntryCount() + "");

        if (fm.getBackStackEntryCount() > 1) {
            fm.popBackStack();
            // super.onBackPressed();
            // return;
        } else {
            if (doubleBackToExitPressedOnce) {
                fm.popBackStack();
                super.onBackPressed();
                return;
            }

            this.doubleBackToExitPressedOnce = true;
            Toast.makeText(this, "Press one more time to exit",
                    Toast.LENGTH_SHORT).show();

            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {

                    doubleBackToExitPressedOnce = false;
                }
            }, 3000);

        }
    }
}
1
Shreyans Patel

戻るボタンは、フラグメントが バックスタックに追加された の順序で移動します。これはデフォルトでナビゲーション機能として提供されます。特定のフラグメントに移動したい場合は、バックスタックから 表示 を実行できます。

0
S.D.

backStackにタグを追加することで処理できます。ここで私の答えを確認してください:

https://stackoverflow.com/a/19477957/1572408

それが役に立てば幸い

0
Rudi