2013-07-31 36 views
1

此问题的SSCCE是available on GitHub片段在使用addToBackStack()时表现得很奇怪

对于将来的读者,最初的示例是branch of the same project,修复程序可用in this diff

这个SSCCE有一个ListView和一排按钮。这些按钮应该改变ListView中的数据,并且ListView行(当单击时)应该打开一个新的片段并在停留在同一活动中时推进后台堆栈。

如果做以下事情,它会产生以下结果:

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

结果:

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

回答

5

我与片段合作的方式,以及我做它: 前进(添加到堆栈),以及backwords(从栈中删除)是两种不同的功能

添加到堆栈和改变片段:

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

我希望能帮助你!

+0

如果只是更新了答案,我忘记了一点“man”它的FragmentManager man = getSupportFragmentManager(); – Jason

+0

你的第二个片段似乎没有解决问题:/ –

+0

第三个做到了:D(稍做修改) –

相关问题