私は現在、1つのActionBarActivity
およびFragments
などのListFragment
を使用して、Android(14 <= SDK <= 21)のアプリケーションを構築しています] _およびMapFragment
、これらは単一のFrameLayout
ビュー内で交換されます。
ActionBarActivityは自動的にフラグメントAを置換/コミットします。その後、ユーザーがボタンをタップすると、ホスティングアクティビティは新しい異なるフラグメントBを置換/コミットします。私の目標は、ユーザーが戻るボタンを押すとすぐにフラグメントAに戻ることです。
今いくつかのコード。
主な活動
_public class MainActivity extends ActionBarActivity implements StopFragment.OnFragmentInteractionListener,
StopItemFragment.OnFragmentInteractionListener {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getFragmentManager();
fragmentManager.enableDebugLogging(true);
...
if (fragmentManager.findFragmentById(R.id.content_frame) == null) {
StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
fragmentManager.beginTransaction()
.replace(R.id.content_frame, list)
.addToBackStack(null)
.commit();
}
...
@Override
public void onFragmentInteraction(String id) {
selectItem(Integer.parseInt(id));
}
private void selectItem(int position) {
StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
...
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
...
}
}
_
問題
addToBackStack()
が呼び出されても、フラグメントBにいるとき、フラグメントAに戻ることはできません。MainActivityは直接閉じられます。しかし、私は自分でバックスタックを運が悪ければ管理しようとしました。フラグメントがスタック上にあることがわかりますが、popBackStackImmediate()
を呼び出すと、フラグメントAがポップアウトされ、フラグメントトランザクションは実行されません。 (最初のバックプレスは何も起こりません、2番目のアクティビティは閉じられます)
FragmentManager logcatも添付します。
http://Pastebin.com/hFLHprL8
まだ解決策を探している人のために。
メインのActivity
クラス(フラグメントをホストしている)では、onBackPressed()
をオーバーライドします。
_@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0 ){
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
_
FragmentにはonBackPressed()
メソッドはなく、このメソッドはactivity
専用です。したがって、戻るキーを押すと、activity
のデフォルトの動作が表示されます。
前のアクティビティにアクセスするか(存在する場合)、アプリを終了します。
ここで、このメソッドをオーバーライドして、activity
に、バックキーを押したときに、バックスタックにフラグメントがある場合、それらをポップアウトするように指示する必要があります(これはaddToBackStack()
が来たときです)写真に)。それ以外の場合は、デフォルトの動作に従います。
これを試してください(注意add not replace fragmentA、およびaddToBackStack() for fragmentB)
StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
fragmentManager.beginTransaction()
.add(R.id.content_frame, list)
.commit();
そして
StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
...
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.addToBackStack("FragmentB")
.commit();
FragmentManager
のbeginTransaction()
およびcommit()
を手動で呼び出す必要がありました。onBackPressed()
をオーバーライドすることで解決します:
@Override
public void onBackPressed() {
...
if (fragmentManager.getBackStackEntryCount() > 1){
fragmentManager.popBackStackImmediate();
fragmentManager.beginTransaction().commit();
} else {
//handle finish
finish(); // Closes app
}
}
AddToBackStack()とpopBackStack()で苦労している場合は、単に使用します
FragmentTransaction ft =getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, new HomeFragment(), "Home");
ft.commit();`
OnBackPressed()でのアクティビティで、タグによってファーグメントを見つけてから、あなたのことをしてください
Fragment home = getSupportFragmentManager().findFragmentByTag("Home");
if (home instanceof HomeFragment && home.isVisible()) {
// do you stuff
}
詳細情報 https://github.com/DattaHujare/NavigationDrawer フラグメントの処理にaddToBackStack()を使用することはありません。
popBackStack()
とpopBackStackImmediatly()
がbackStackに(ポップしたい)そのフラグメントを追加しなかったという事実が原因です。これを行うには、フラグメントを追加/置換するトランザクションを作成するときにaddToBackStack()を呼び出す必要があります。