アプリケーションにはactivity
が1つとfragments
が複数あります。
2つのメインフラグメントA(left) and B(right)。
Fragment A1 called from A
B1 called from B
B2 called from B1
すべてのfragments
には個別の戻るボタンがあります。
fragment
A1の戻るボタンを押すと、[〜#〜] a [〜#〜]に戻るはずです。戻るボタンも同様ですfrom B2が押され、B1が表示され、from B1から[〜#〜] b [〜#〜]等々。
このタイプの機能を実装する方法は?
public void onBackPressed()
{
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.popBackStack();
}
同様のシナリオを今実装しました。
アクティビティ「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
@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つのいずれかを実行できます。
私の場合、それは後者だったので、オーバーライドされたonBackPressed
メソッドを以前の回答から以下のように変更しました
@Override
public void onBackPressed() {
if(getFragmentManager().getBackStackEntryCount() == 1) {
moveTaskToBack(false);
}
else {
super.onBackPressed();
}
}
このコードは、ロジックが少なく、カスタムコードよりもフレームワークに依存しているため、よりシンプルです。残念ながら、最初の状況ではコードを実装する必要がなかったため、どうにか実装できませんでした。
ただやる
getActivity().getFragmentManager().popBackStack();
説明したように、独自のバックスタック実装を実装する必要があります here。
フラグメントの[戻る]ボタンをクリックするたびにpopFragments()
を呼び出し、フラグメント間を移動するたびにpushFragments()
を呼び出すことができます。
これを試してみてください。
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);
}
}
}
戻るボタンは、フラグメントが バックスタックに追加された の順序で移動します。これはデフォルトでナビゲーション機能として提供されます。特定のフラグメントに移動したい場合は、バックスタックから 表示 を実行できます。