【问题标题】:Fragments Behave Weirdly When Using addToBackStack()片段在使用 addToBackStack() 时表现异常
【发布时间】:2013-07-31 18:43:44
【问题描述】:

此问题的 SSCCE 是 available on GitHub

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

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

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

  1. 打开应用程序。
  2. 点击列表视图。 - FragmentTransaction.replace(...)addToBackStack(true)
  3. 点击任意按钮。 - FragmentTransaction.replace(...)addToBackStack(false)
  4. 点击返回按钮。

结果:

两个片段都变得可见,但我只想显示第一个加载的片段(代码中的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);
    }
}

【问题讨论】:

    标签: android android-fragments back-stack


    【解决方案1】:

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

    添加到堆栈并更改片段:

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

    返回堆栈:

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

    希望能帮到你!

    【讨论】:

    • 如果刚刚更新了答案,我忘了一个小东西,“人”它的 FragmentManager man = getSupportFragmentManager();
    • 第三个做了:D(稍作修改)
    • 我将复制我在我的代码中所做的事情并且它运行完美:我有三件事 Fragment - MyApplication 类 - MainActivity 在活动中我有这些功能从我调用到 MyApp 类 MyApp.goMainBackStack(getActivity ()); public void goMainBackStack(Activity a) { MainActivity fca = (MainActivity)a; fca.goBackStackMain(); } 在主要公共无效 goBackStackMain() { man.popBackStack(man.getBackStackEntryAt(0).getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE); } 和我添加到堆栈的方式与答案相同
    • 如果您想了解我如何使用您的代码,请查看 GitHub 链接。
    猜你喜欢
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多