片段行为异常使用addToBackStack当() [英] Fragments Behave Weirdly When Using addToBackStack()
问题描述
有关此问题的SSCCE是可以在GitHub上。
有关未来的读者,原来的例子就是在同一个项目的分支。
这SSCCE有ListView和一排按钮。这些按钮都应该改变在ListView中的数据,并在ListView行(点击时)都应该打开一个新的片段,推进backstack而住在同一个活动。
如果做以下事情,它会产生以下结果:
- 打开应用程序。
- 点击ListView控件。 -
FragmentTransaction.replace(...)
与addToBackStack(真)
- 点击任何按钮。 -
FragmentTransaction.replace(...)
与addToBackStack(假)
- 点击返回按钮。
结果:
两个片段可见,但我只希望第一个加载的片段(ListTwoFragment <$ C C $>在code)来显示。请问这是怎么片段应该工作?如果是这样,我怎么能得到预期的效果?
MainActivity.java:
公共类MainActivity扩展FragmentActivity实现ListTwoFragment.Callbacks,
ListThreeFragment.Callbacks {
公共静态最后弦乐KEY_ARGS =ARGS;
私人字符串curUri =;
私人字符串curArgs =;
@覆盖
保护无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.activity_main);
selectContent(假);
}
私人无效selectContent(布尔addToBackStack){
片段片段
如果(curUri.isEmpty()){
//使用默认片段
片段=新ListTwoFragment();
curUri = ListTwoFragment.class.getName();
}
其他 {
尝试 {
类&LT;片断&gt; fragmentClass =(类&LT;片断&gt;)的Class.forName(curUri);
片段= fragmentClass.newInstance();
}
赶上(例外五){// ClassNotFound的,IllegalAccess等。
返回;
}
}
//配置片段
捆绑的args =新包();
args.putString(KEY_ARGS,curArgs);
fragment.setArguments(参数);
attachFragment(片段,addToBackStack,curUri +;+ curArgs,R.id.fragment_container);
}
保护无效attachFragment(片段片段,布尔addToBackStack,字符串变量,INT replaceId){
FragmentTransaction交易= getSupportFragmentManager()的BeginTransaction()。
transaction.replace(replaceId,片段,标记);
如果(addToBackStack)transaction.addToBackStack(标签);
器transaction.commit();
}
@覆盖
公共无效onTwoButtonClick(字符串名称){
curUri = ListTwoFragment.class.getName();
curArgs =称号;
selectContent(假);
}
@覆盖
公共无效onTwoListClick(){
curUri = ListThreeFragment.class.getName();
curArgs =;
selectContent(真正的);
}
@覆盖
公共无效onThreeButtonClick(字符串名称){
curUri = ListThreeFragment.class.getName();
curArgs =称号;
selectContent(假);
}
}
我正与片段,而我做的方式: 前进(添加到栈),和backwords(从堆栈中删除)是两个不同的功能
添加到协议栈和改变片段:
公共无效changeFragmentAddToStack(片段myNewFragment){
FragmentTransaction T = getSupportFragmentManager()的BeginTransaction()。
t.add(R.id.main_fragment,myNewFragment);
t.addToBackStack(空);
t.commit();
}
要回到堆栈:
公共无效goBackStackMain(){
FragmentManager人= getSupportFragmentManager();
如果(man.getBackStackEntryCount()大于0){
man.popBackStack(man.getBackStackEntryAt(0).getName(),FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
如果你想做到既:要返回堆栈并更改片段:
公共无效goBackStackAndReplaceFragment(片段myNewFragment){
FragmentManager人= getSupportFragmentManager();
如果(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();
}
我希望能帮助你!
An SSCCE for this issue is available on GitHub.
For future readers, the original example is on a branch of the same project.
This SSCCE has a ListView and a row of buttons. The buttons are supposed to change the data in the ListView, and the listView rows (when clicked) are supposed to open a new fragment and advance the backstack while staying in the same activity.
If do the following things, it produces the following result:
- Open the app.
- Tap the ListView. -
FragmentTransaction.replace(...)
withaddToBackStack(true)
- Tap any of the buttons. -
FragmentTransaction.replace(...)
withaddToBackStack(false)
- Tap the back button.
Result:
Both fragments become visible, but I only want the first loaded fragment (ListTwoFragment
in code) to display. Is this how fragments are supposed to work? If so, how can I get the desired effect?
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);
}
}
I'm working with Fragments to, and the way I'm doing it: to go forward (add to stack), and backwords (remove from stack) are two different functions
to Add to Stack and change Fragment:
public void changeFragmentAddToStack(Fragment myNewFragment) {
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.add(R.id.main_fragment, myNewFragment);
t.addToBackStack(null);
t.commit();
}
To go back Stack:
public void goBackStackMain() {
FragmentManager man = getSupportFragmentManager();
if(man.getBackStackEntryCount()>0){
man.popBackStack(man.getBackStackEntryAt(0).getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
And if you want to do both: To go back stack and change fragment:
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();
}
I hope to help you !
这篇关于片段行为异常使用addToBackStack当()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!