In Fragment on back button pressed Activity is blank

前端 未结 11 1633
囚心锁ツ
囚心锁ツ 2020-11-29 20:04

I have an Activity and many fragments inflated in same FrameLayout



        
相关标签:
11条回答
  • 2020-11-29 20:14

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

    public void onBackPressed() { 
       if (getFragmentManager().getBackStackEntryCount() == 1) {
            finish();
       } else {
            super.onBackPressed();
       }
    }
    
    0 讨论(0)
  • 2020-11-29 20:15

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

        // 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();
        }
    
    0 讨论(0)
  • 2020-11-29 20:21

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

    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):

    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 isNavDrawerOpen method:

    bool isNavDrawerOpen()
    {
        return drawerLayout != null && drawerLayout.IsDrawerOpen(Android.Support.V4.View.GravityCompat.Start);
    }
    
    0 讨论(0)
  • 2020-11-29 20:22

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

    @Override
    public void onBackPressed() {
        int fragments = getFragmentManager().getBackStackEntryCount();
        if (fragments == 1) { 
            // make layout invisible since last fragment will be removed
        }
        super.onBackPressed();
    }
    
    0 讨论(0)
  • 2020-11-29 20:27
    @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();
    
    0 讨论(0)
  • 2020-11-29 20:33

    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:

    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:

    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.

    0 讨论(0)
提交回复
热议问题