以编程方式返回到后面的片段
说我有一个活动,有碎片添加编程:
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()
做了两件事情:
- 从您指定的容器(C)中删除当前添加的片段(A)
- 添加新的片段(B)到相同的容器
这2个操作是作为Backstacklogging/事务保存的。 请注意,片段A保持created
状态,其视图被破坏。
现在popBackStack()
您添加到BackStack的最后一个事务。
在这种情况下,这将是2个步骤:
- 从C中删除B.
- 将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();