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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20340303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:42:22  来源:igfitidea点击:

In Fragment on back button pressed Activity is blank

androidandroid-fragments

提问by Filip Luchianenco

I have an Activity and many fragments inflated in same FrameLayout

我有一个 Activity 和许多碎片在同一个膨胀 FrameLayout

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

example: mainActivity > any fragment (press back button) > activity is blank.

示例:mainActivity > 任何片段(按后退按钮)> 活动为空白。

In onCreate:

在 onCreate 中:

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

When I start a fragment:

当我开始一个片段时:

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

I suppose I need to make the frameLayout's visibility GONEagain on back pressed, but how do I do this?

我想我需要GONE在按下后再次使 frameLayout 的可见性,但我该怎么做?



I tried onBackPressedand set layout.setVisibility(View.GONE);but I cannot go back through fragments, as I go directly to main page.

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

回答by Sampath Kumar

If you have more than one fragment been used in the activity or even if you have only one fragment then the first fragment should not have addToBackStack defined. Since this allows back navigation and prior to this fragment the empty activity layout will be displayed.

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

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

But for the other fragment you need to have this defined otherwise the back will not navigate to earlier screen (fragment) instead the application might shutdown.

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

回答by Goodlife

@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();
        }
    }
}

To add a fragment

添加片段

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

回答by irscomp

Sorry for the late response.

回复晚了非常抱歉。

You don't have to add ft.addToBackStack(null);while adding first fragment.

您不必添加 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

回答by Edgar Sousa

If you want to track by the fragments you should override the onBackPressedmethod, like this

如果您想通过片段进行跟踪,则应覆盖该onBackPressed方法,如下所示

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

回答by JRomero

You can override onBackPressedand check to see if there is anything on the backstack.

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

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

回答by Sileria

Just don't add the first fragment to back stack

只是不要将第一个片段添加到后堆栈

Here is the Kotlin code that worked for me.

这是对我有用的 Kotlin 代码。

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

回答by gMale

On a recent personal project, I solved this by not calling addToBackStackif the stack is empty.

在最近的一个个人项目中,我通过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);
    }

Here's my full implementation:

这是我的完整实现:

    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();
    }

回答by Filip Luchianenco

I still could not fix the issue through getBackStackEntryCount()and I solved my issue by making the main page a fragment too, so in the end I have an activity with a FrameLayoutonly; and all other fragments including the main page I inflate into that layout. This solved my issue.

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

回答by Jemshit Iskenderov

irscomp's solution works if you want to end activity when back button is pressed on first fragment. But if you want to track all fragments, and go back from one to another in back order, you add all fragments to stack with:

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

ft.addToBackStack(null);

and then, add this to the end of onCreate() to avoid blank screen in last back pressed; you can use getSupportFragmentManager() or getFragmentManager() depending on your API:

然后,将此添加到 onCreate() 的末尾以避免最后一次按下时出现空白屏幕;您可以根据您的 API 使用 getSupportFragmentManager() 或 getFragmentManager() :

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

Final words: I don't suggest you to use this solution, because if you go from fragment1 to fragment 2 and vice versa 10 times, when you press back button 10 times it will do it in back order which users will not want it.

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

回答by Mehdi Dehghani

Almost same as Goodlife's answer, but in Xamarin.Androidway:

Goodlife的回答几乎相同,但Xamarin.Android方式不同:

Load fragment (I wrote helper method for that, but it's not necessary):

加载片段(我为此编写了辅助方法,但这不是必需的):

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();
}

Back button (in MainActivity):

后退按钮(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();
    }
}

And isNavDrawerOpenmethod:

isNavDrawerOpen方法:

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