GitHub 上提供了针对此问题的 SSCCE 。
对于未来的读者,原始示例位于同一项目的一个分支上,此 diff中提供了修复程序。
这个 SSCCE 有一个 ListView 和一排按钮。按钮应该更改 ListView 中的数据,并且 listView 行(单击时)应该打开一个新片段并在保持相同活动的同时推进 backstack。
如果执行以下操作,则会产生以下结果:
- 打开应用程序。
- 点击列表视图。-
FragmentTransaction.replace(...)
与addToBackStack(true)
- 点击任何按钮。-
FragmentTransaction.replace(...)
与addToBackStack(false)
- 点击后退按钮。
结果:
两个片段都变得可见,但我只希望显示第一个加载的片段(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);
}
}