以编程方式返回到后面的片段

说我有一个活动,有碎片添加编程:

private void animateToFragment(Fragment newFragment, String tag) { FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(R.id.fragment_container, newFragment, tag); ft.addToBackStack(null); ft.commit(); } 

什么是返回到可见的前一个片段的最佳方法?

我发现在Android的button点击触发后退buttonfunction,但我想模拟一个后退键事件是不正确的方式来解决它(我也不能让它工作):

 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK)); 

调用finish()只是closures了我不感兴趣的活动。

有没有更好的方法去做这件事?

看看getFragmentManager().popBackStack()方法(有几种可供select)

http://developer.android.com/reference/android/app/FragmentManager.html#popBackStack();

为了详细说明所提供的其他答案,这是我的解决scheme(放置在一个活动中):

 @Override public void onBackPressed(){ FragmentManager fm = getFragmentManager(); if (fm.getBackStackEntryCount() > 0) { Log.i("MainActivity", "popping backstack"); fm.popBackStack(); } else { Log.i("MainActivity", "nothing on backstack, calling super"); super.onBackPressed(); } } 

当我们更新/添加片段时,

应该包含.addToBackStack()

 getSupportFragmentManager().beginTransaction() .add(detailFragment, "detail") // Add this transaction to the back stack (name is an optional name for this back stack state, or null). .addToBackStack(null) .commit(); 

之后,如果我们给getFragments.popBackStackImmediate()将返回true,如果我们添加/更新片段,并回到当前屏幕。

replace()做了两件事情:

  1. 从您指定的容器(C)中删除当前添加的片段(A)
  2. 添加新的片段(B)到相同的容器

这2个操作是作为Backstacklogging/事务保存的。 请注意,片段A保持created状态,其视图被破坏。

现在popBackStack()您添加到BackStack的最后一个事务。

在这种情况下,这将是2个步骤:

  1. 从C中删除B.
  2. 将A添加到C

在此之后,片段B变得detached ,如果你不参考,它将被垃圾收集。

要回答你的问题的第一部分,没有onCreate()调用,因为FragmentB保持created状态。 而问题的第二部分的答案是有点长。

首先,理解你实际上并没有将Fragments添加到Backstack中,这是很重要的,你需要添加FragmentTransactions 。 所以当你认为你“用碎片Breplace,把碎片A添加到后端堆栈”时,你实际上把这个整个操作添加到了后端堆栈 – 即用BreplaceA.这个replace包括2个操作 – 删除A和添加B 。

然后,下一步是popup包含此replace的事务。 所以你没有popupFragmentA,你正在倒转“删除A,添加B”,反过来就是“删除B,加A”。

然后最后一步应该更清楚了–FragmentManager没有意识到的B,所以当你在最后一步用B代替A时,B需要通过早期的生命周期方法onAttach()onCreate()

下面的代码说明了发生的事情。

 FragmentManager fm = getFragmentManager(); FragmentA fragmentA = new FragmentA(); FragmentB fragmentB = new FragmentB(); // 1. Show A fm.beginTransaction() .add(fragmentA, R.id.container) .commit(); // 2. Replace A with B // FragmentManager keeps reference to fragmentA; // it stays attached and created; fragmentB goes // through lifecycle methods onAttach(), onCreate() // and so on. fm.beginTransaction() .replace(fragmentB, R.id.container) .addToBackstack(null) .commit(); // 2'. Alternative to replace() method fm.beginTransaction() .remove(fragmentA) .add(fragmentB, R.id.container) .addToBackstack(null) .commit(); // 3. Reverse (2); Result - A is visible // What happens: // 1) fragmentB is removed from container, it is detached now; // FragmentManager doesn't keep reference to it anymore // 2) Instance of FragmentA is placed back in the container // Now your Backstack is empty, FragmentManager is aware only // of FragmentA instance fm.popBackStack(); // 4. Show B // Since fragmentB was detached, it goes through its early // lifecycle methods: onAttach() and onCreate(). fm.beginTransaction() .replace(fragmentB, R.id.container) .addToBackstack(null) .commit(); 

将这些行添加到onBackPressed()方法中。 popBackStackImmediate()方法可以让你回到前一个片段,如果你有任何的片段“

 if(getFragmentManager().getBackStackEntryCount() > 0){ getFragmentManager().popBackStackImmediate(); } else{ super.onBackPressed(); } 

`

使用以下代码以编程方式返回到以前的片段。

 if ( getFragmentManager().getBackStackEntryCount() > 0) { getFragmentManager().popBackStack(); return; } super.onBackPressed(); 

此解决scheme完美适用于基于底部条的片段导航,当您想要在主要片段中按下时closures该应用程序。

另一方面,当您打开我的代码中定义为“DetailedPizza”的辅助片段(片段中的片段)时,它将返回以前的主要片段的状态。 干杯!

里面的活动按回来把这个:

 Fragment home = getSupportFragmentManager().findFragmentByTag("DetailedPizza"); if (home instanceof FragmentDetailedPizza && home.isVisible()) { if (getFragmentManager().getBackStackEntryCount() != 0) { getFragmentManager().popBackStack(); } else { super.onBackPressed(); } } else { //Primary fragment moveTaskToBack(true); } 

并启动其他片段,如下所示:

 Fragment someFragment = new FragmentDetailedPizza(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.replace(R.id.container_body, someFragment, "DetailedPizza"); transaction.addToBackStack("DetailedPizza"); transaction.commit();