我已经实现了Navigation Drawer,它是Activity的子类。我的应用程序中有很多片段。我的问题在这里
想象一下有3个片段:
Fragment_1:Fragment_2:Fragment_3
当我启动应用程序时,会加载Fragment_1 当我点击Fragment_1上的某些组件时,我已导航到Fragment_2,依此类推..
所以它就像
Fragment_1> Fragment_2> Fragment_3
当我从Fragment_2按回键时,我导航回Fragment_1 但是当我从Fragment_3按下键时,我导航回Fragment_1(而不是Fragment_2)
我想在Back Key press
上的应用程序中输入这样的内容Fragment_1< Fragment_2< Fragment_3
我使用Fragment,FragmentManager,FragmentTransaction如下:
MyFragment fragment = new MyFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).addToBackStack(null)commit();
我尝试在MainActivity中覆盖onBackPressed():
@Override
public void onBackPressed() {
getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0)
super.onBackPressed();
}
答案 0 :(得分:35)
将您的Activity#onBackPressed()
方法更新为:
@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
您的实现不起作用的原因是因为方法FragmentManager#popBackStack()
是异步的,并且在调用之后不会发生。
来自文档:
此函数是异步的 - 它将请求排入pop,但在应用程序返回其事件循环之前不会执行该操作。
答案 1 :(得分:3)
您必须按照此处的说明实现自己的backstack实现
Separate Back Stack for each tab in Android using Fragments
只要单击片段中的后退按钮,就可以调用popFragments(),只要从一个片段导航到另一个片段,就可以调用pushFragments()。
简而言之,
public void onBackPressed()
{
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.popBackStack();
}
答案 2 :(得分:2)
tric在/**
* if there is a fragment and the back stack of this fragment is not empty,
* then emulate 'onBackPressed' behaviour, because in default, it is not working.
*
* @param fm the fragment manager to which we will try to dispatch the back pressed event.
* @return {@code true} if the onBackPressed event was consumed by a child fragment, otherwise
*/
public static boolean dispatchOnBackPressedToFragments(FragmentManager fm) {
List<Fragment> fragments = fm.getFragments();
boolean result;
if (fragments != null && !fragments.isEmpty()) {
for (Fragment frag : fragments) {
if (frag != null && frag.isAdded() && frag.getChildFragmentManager() != null) {
// go to the next level of child fragments.
result = dispatchOnBackPressedToFragments(frag.getChildFragmentManager());
if (result) return true;
}
}
}
// if the back stack is not empty then we pop the last transaction.
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
fm.executePendingTransactions();
return true;
}
return false;
}
。
这也是我用于嵌套片段的......:
onBackPressed
和我的 if (!FragmentUtils.dispatchOnBackPressedToFragments(fm)) {
// if no child fragment consumed the onBackPressed event,
// we execute the default behaviour.
super.onBackPressed();
}
:
git reflog
答案 3 :(得分:0)
在主要活动的标签更改中使用此代码清除堆栈。
int count = getFragmentManager().getBackStackEntryCount();
if(count>0){
for (int i = 0; i <count; i++) {
getFragmentManager().popBackStack();
}
}
然后在你的主要活动的背面按下
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onbackpressed();
}
else {
getFragmentManager().popBackStack();
}
}
答案 4 :(得分:0)
以下是我的工作和测试代码,这将对您有所帮助
private static final int TIME_INTERVAL = 2000;
private long mBackPressed;
private void applyExit() {
if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) {
finish();
} else {
Toast.makeText(this,"Press Again to exit",Toast.LENGTH_LONG).show();
}
mBackPressed = System.currentTimeMillis();
}
@Override
public void onBackPressed() {
fm = getSupportFragmentManager();
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
if (fm.getFragments().size() <= 1) {
applyExit();
} else {
for (Fragment frag : fm.getFragments()) {
if (frag == null) {
applyExit();
return;
}
if (frag.isVisible()) {
FragmentManager childFm = frag.getChildFragmentManager();
if (childFm.getFragments() == null) {
super.onBackPressed();
return;
}
if (childFm.getBackStackEntryCount() > 0) {
childFm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
return;
} else {
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
return;
}
}
}
}
}