在按下后退按钮的片段中,活动为空白

时间:2013-12-03 00:01:01

标签: android android-fragments

我有一个活动和许多片段在同一个FrameLayout

中膨胀
<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

示例:mainActivity&gt;任何片段(按下后退按钮)&gt;活动是空白的。

on onCreate:

layout = (FrameLayout)findViewById(R.id.content_frame);
layout.setVisibility(View.GONE);

当我开始片段时:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, profileFragment);
ft.addToBackStack(null);
ft.commit();
layout.setVisibility(View.VISIBLE);

我想我需要在后退时再次进行frameLayout的可见性GONE,但我该怎么做?


我尝试了onBackPressed并设置了layout.setVisibility(View.GONE);但我无法通过片段返回,因为我直接转到主页。

11 个答案:

答案 0 :(得分:112)

如果您在活动中使用了多个片段,或者即使您只有一个片段,那么第一个片段也不应该定义addToBackStack。由于这允许返回导航,因此在此片段之前将显示空活动布局。

 // fragmentTransaction.addToBackStack() // dont include this for your first fragment.

但是对于另一个片段,你需要定义它,否则后面将不会导航到早期的屏幕(片段),而是应用程序可能会关闭。

答案 1 :(得分:39)

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

添加片段

 getSupportFragmentManager().beginTransaction()
                .replace(R.id.layout_main, dashboardFragment, getString(R.string.title_dashboard))
                .addToBackStack(getString(R.string.title_dashboard))
                .commit();

答案 2 :(得分:22)

对于迟到的回复感到抱歉。

添加第一个片段时,您不必添加 ft.addToBackStack(null);

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, profileFragment);
// ft.addToBackStack(null); --remove this line.
ft.commit();
// ... rest of code

答案 3 :(得分:17)

如果您想按片段进行追踪,则应覆盖onBackPressed方法,例如

public void onBackPressed() { 
   if (getFragmentManager().getBackStackEntryCount() == 1) {
        finish();
   } else {
        super.onBackPressed();
   }
}

答案 4 :(得分:14)

您可以覆盖onBackPressed并检查Backstack上是否有任何内容。

@Override
public void onBackPressed() {
    int fragments = getFragmentManager().getBackStackEntryCount();
    if (fragments == 1) { 
        // make layout invisible since last fragment will be removed
    }
    super.onBackPressed();
}

答案 5 :(得分:2)

在最近的个人项目中,如果堆栈为空,我通过不调用addToBackStack解决了这个问题。

    // don't add the first fragment to the backstack
    // otherwise, pressing back on that fragment will result in a blank screen
    if (fragmentManager.getFragments() != null) {
        transaction.addToBackStack(tag);
    }

这是我的全面实施:

    String tag = String.valueOf(mCurrentSectionId);
    FragmentManager fragmentManager = mActivity.getSupportFragmentManager();
    Fragment fragment = fragmentManager.findFragmentByTag(tag);

    if (fragment != null) {
        // if the fragment exists then no need to create it, just pop back to it so
        // that repeatedly toggling between fragments doesn't create a giant stack
        fragmentManager.popBackStackImmediate(tag, 0);
    } else {
        // at this point, popping back to that fragment didn't happen
        // So create a new one and then show it
        fragment = createFragmentForSection(mCurrentSectionId);

        FragmentTransaction transaction = fragmentManager.beginTransaction()
                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .replace(R.id.main_content, fragment, tag);

        // don't add the first fragment to the backstack
        // otherwise, pressing back on that fragment will result in a blank screen
        if (fragmentManager.getFragments() != null) {
            transaction.addToBackStack(tag);
        }

        transaction.commit();
    }

答案 6 :(得分:2)

只需不将第一个片段添加到堆栈中

这是对我有用的Kotlin代码。

    val ft = supportFragmentManager.beginTransaction().replace(container, frag)
    if (!supportFragmentManager.fragments.isEmpty()) ft.addToBackStack(null)
    ft.commit()

答案 7 :(得分:1)

我仍然无法通过getBackStackEntryCount()解决问题,我也通过将主页面设为片段来解决我的问题,所以最后我的活动只有FrameLayout;和所有其他片段,包括主页面,我膨胀到该布局。这解决了我的问题。

答案 8 :(得分:1)

如果您想在第一个片段上按下后退按钮时结束活动,则irscomp的解决方案有效。但是如果你想跟踪所有片段,并按照后面的顺序从一个片段返回到另一个片段,则将所有片段添加到堆栈中:

ft.addToBackStack(null);

然后,将其添加到onCreate()的末尾以避免在最后一次按下时出现空白屏幕;您可以使用getSupportFragmentManager()或getFragmentManager(),具体取决于您的API:

FragmentManager fm = getSupportFragmentManager();
    fm.addOnBackStackChangedListener(new OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            if(getSupportFragmentManager().getBackStackEntryCount() == 0) finish();             
        }
});

最后的话:我不建议你使用这个解决方案,因为如果你从fragment1转到片段2,反之亦然10次,当你按回10次按钮时,它会按顺序执行,用户不会想要它。

答案 9 :(得分:1)

Goodlife 的答案几乎相同,但是以Xamarin.Android的方式:

加载片段(我为此编写了帮助方法,但它没有必要):

public void LoadFragment(Activity activity, Fragment fragment, string fragmentTitle = "")
{
    var fragmentManager = activity.FragmentManager;
    var fragmentTransaction = fragmentManager.BeginTransaction();

    fragmentTransaction.Replace(Resource.Id.mainContainer, fragment);
    fragmentTransaction.AddToBackStack(fragmentTitle);

    fragmentTransaction.Commit();
}

后退按钮(MainActivity 中的):

public override void OnBackPressed()
{
    if (isNavDrawerOpen()) drawerLayout.CloseDrawers();
    else
    {
        var backStackEntryCount = FragmentManager.BackStackEntryCount;

        if (backStackEntryCount == 1) Finish();
        else if (backStackEntryCount > 1) FragmentManager.PopBackStack();
        else base.OnBackPressed();
    }
}

isNavDrawerOpen方法:

bool isNavDrawerOpen()
{
    return drawerLayout != null && drawerLayout.IsDrawerOpen(Android.Support.V4.View.GravityCompat.Start);
}

答案 10 :(得分:1)

在处理Firebase的Ui登录屏幕时,我遇到了同样的问题。按下“后退”按钮时,它会留下一个空白屏幕。

要解决该问题,我刚刚在finish()方法中为“活动”调用了onStop()。像魅力一样工作。