在 Android 中返回 onBackPressed 上的上一个片段

Back to previous fragment on onBackPressed in Android

我不熟悉 Android 开发和使用 Android 的默认导航抽屉布局开发应用程序。

我在应用程序中使用片段。

我想在下一个片段上按下后退按钮时返回到上一个片段。 onBackPress 必须实现以下功能

  1. 在下一个片段时返回上一个片段
  2. 导航抽屉打开时关闭抽屉
  3. 在 fragment1 中双击后退退出应用程序

这是我在 MainActivity 中的代码 在创建新片段时

// replacing the fragment
if (fragment != null) {
     FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
     ft.replace(R.id.content_frame, fragment);
  ft.commit();
}

onBackPress

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else if (getFragmentManager().getBackStackEntryCount() > 0) {
        FragmentManager fm = getSupportFragmentManager();
        fm.popBackStack();
    } else {
        super.onBackPressed();
    }
}

但这不起作用,按下后退会退出应用程序,除非导航抽屉打开时关闭。

您必须将 FragmentTransaction 中的 Fragment 添加到后台堆栈。

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
     ft.replace(R.id.content_frame, fragment).addtoBackStack(null).commit();

通过提供标签 null,他们都将按该标签分组。因此,如果您需要将它们全部关闭,您可以这样做或导航到某个特定的。

我也不会使用 replace(),因为那个在 backstack 上的错误令人难以置信。

尝试使用 remove() 然后 add()

您没有将片段添加到后台堆栈。你只需要做

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
 .replace(R.id.content_frame, fragment);
 .addToBackStack(null);
 .commit();

而且由于Backstack实际上是由后退按钮处理的,所以在onBackPressed()中不需要处理这种情况,因此可以将其更改为:

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

您应该将您的片段添加到返回堆栈并以这种方式修改您的代码:

// this variable is needed to know how many times the back key has been pressed.
// It is incremented and reset accordingly to the logic you described
int mBackPressCount = 0;

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        if (getFragmentManager().getBackStackEntryCount() == 0) {
            // if there are no fragments in your back stack check the mBackPressCount
            if (mBackPressCount++ > 0) {
                // if you pressed back for the second time this line will terminate the activity
                super.onBackPressed();
            } 
        } else {
            // this line will pop the fragment from the back stack,
            // no need to pop it manually
            super.onBackPressed();
        }
    }
}

将片段添加到返回堆栈:

if (fragment != null) {
     FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
     ft.replace(R.id.content_frame, fragment);
     ft.addToBackStack(null);
     ft.commit();

     // when you add a fragment you should reset the back press count
     mBackPressCount = 0;
}

打开和关闭抽屉时重置mBackPressCount。如果您按下后退键一次并打开抽屉,则计数器必须再次设置为 0。

DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
    @Override
    public void onDrawerSlide(View drawerView, float slideOffset) {

    }

    @Override
    public void onDrawerOpened(View drawerView) {
        mBackPressCount = 0;
    }

    @Override
    public void onDrawerClosed(View drawerView) {
        mBackPressCount = 0;
    }

    @Override
    public void onDrawerStateChanged(int newState) {

    }
});