使用addToBackStack()时片段表现得很奇怪

时间:2013-07-31 18:43:44

标签: android android-fragments back-stack

此问题的SSCCE为available on GitHub

对于未来的读者,原始示例位于branch of the same project,修复程序可用in this diff

这个SSCCE有一个ListView和一排按钮。这些按钮应该改变ListView中的数据,并且listView行(当被点击时)应该打开一个新片段并在保持同一活动的同时推进backstack。

如果执行以下操作,则会产生以下结果:

  1. 打开应用程序。
  2. 点按ListView。 - FragmentTransaction.replace(...)addToBackStack(true)
  3. 点按任意按钮。 - FragmentTransaction.replace(...)addToBackStack(false)
  4. 点按后退按钮。
  5. 结果:

    Overlapping Fragments

    两个片段都可见,但我只想显示第一个加载的片段(代码中为ListTwoFragment)。这是片段应该如何工作?如果是这样,我怎样才能达到预期效果?

    MainActivity.java:

    public class MainActivity extends FragmentActivity implements ListTwoFragment.Callbacks,
        ListThreeFragment.Callbacks {
        public static final String KEY_ARGS = "args";
    
        private String curUri = "";
        private String curArgs = "";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            selectContent(false);
        }
    
        private void selectContent(boolean addToBackStack) {
            Fragment fragment;
    
            if (curUri.isEmpty()) {
                // Use default fragment
                fragment = new ListTwoFragment();
                curUri = ListTwoFragment.class.getName();
            }
            else {
                try {
                    Class<Fragment> fragmentClass = (Class<Fragment>) Class.forName(curUri);
                    fragment = fragmentClass.newInstance();
                }
                catch (Exception e) { // ClassNotFound, IllegalAccess, etc.
                    return;
                }
            }
    
            // Configure fragment
            Bundle args = new Bundle();
            args.putString(KEY_ARGS, curArgs);
            fragment.setArguments(args);
    
            attachFragment(fragment, addToBackStack, curUri + ";" + curArgs, R.id.fragment_container);
        }
    
        protected void attachFragment(Fragment fragment, boolean addToBackStack, String tag, int replaceId) {
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(replaceId, fragment, tag);
            if (addToBackStack) transaction.addToBackStack(tag);
            transaction.commit();
        }
    
        @Override
        public void onTwoButtonClick(String title) {
            curUri = ListTwoFragment.class.getName();
            curArgs = title;
            selectContent(false);
        }
    
        @Override
        public void onTwoListClick() {
            curUri = ListThreeFragment.class.getName();
            curArgs = "";
            selectContent(true);
        }
    
        @Override
        public void onThreeButtonClick(String title) {
            curUri = ListThreeFragment.class.getName();
            curArgs = title;
            selectContent(false);
        }
    }
    

1 个答案:

答案 0 :(得分:5)

我正在使用Fragments,以及我正在这样做的方式: 前进(添加到堆栈),后退(从堆栈中删除)是两个不同的功能

添加到堆栈并更改片段:

public void changeFragmentAddToStack(Fragment myNewFragment) {
        FragmentTransaction t = getSupportFragmentManager().beginTransaction();
        t.add(R.id.main_fragment, myNewFragment);
        t.addToBackStack(null);
        t.commit();
    }

返回Stack:

        public void goBackStackMain() {
    FragmentManager man = getSupportFragmentManager();

                if(man.getBackStackEntryCount()>0){ 
                    man.popBackStack(man.getBackStackEntryAt(0).getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
            }
}

如果您想同时执行这两项操作:返回堆栈并更改片段:

    public void goBackStackAndReplaceFragment(Fragment myNewFragment) {
FragmentManager man = getSupportFragmentManager();
            if(man.getBackStackEntryCount()>0){ 
                int n = man.getBackStackEntryCount();
                man.popBackStack(man.getBackStackEntryAt(n-1).getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
            }

        FragmentTransaction t = getSupportFragmentManager().beginTransaction();
        t.replace(R.id.main_fragment, myNewFragment);
        t.commit();
    }

我希望能帮到你!