得到例外:片段已经激活

Lee*_*fin 58 android android-emulator android-intent android-layout android-fragments

我有一个片段 ;

MyFragment myFrag = new MyFragment();
Run Code Online (Sandbox Code Playgroud)

我把bundle数据放到这个片段:

Bundle bundle = new Bundle(); 
bundle.putString("TEST", "test");
myFrag.setArguments(bundle);
Run Code Online (Sandbox Code Playgroud)

然后,我用这个替换旧片段并放在backstack上:

//replace old fragment
fragmentTransaction.replace(R.id.fragment_placeholder, myFrag, "MyTag");
//put on backstack
fragmentTransaction.addToBackStack(null);
//commit & get transaction ID
int transId = fragmentTransaction.commit();
Run Code Online (Sandbox Code Playgroud)

后来,我使用上面的事务ID()弹出backstacktransId:

//pop the transaction from backstack
fragmentManager.popBackStack(transId,FragmentManager.POP_BACK_STACK_INCLUSIVE); 
Run Code Online (Sandbox Code Playgroud)

后来,我再次将bundle数据作为参数设置到我的fragment(myFrag):

//Got Java.lang.IllegalStateException: fragment already active
myFrag.setArguments(bundle);
Run Code Online (Sandbox Code Playgroud)

如您所见,我的上述代码异常Java.lang.IllegalStateException: fragment already active.虽然我已经从backstack弹出了它的事务,但我不明白为什么 myFrag 仍然有效.无论如何,因为我得到了例外,我认为我别无选择,只能取消激活片段,所以,我做了:

Fragment activeFragment = fragMgr.findFragmentByTag("MyTag");
fragmentTransaction.remove(activeFragment);
Run Code Online (Sandbox Code Playgroud)

我不确定我的上面的代码是否真的可以解除片段,因为我没有找到如何去激活片段.:(

之后,当我尝试再次将包数据设置为我的片段myFrag时,我仍然遇到同样的错误:

Java.lang.IllegalStateException: fragment already active
Run Code Online (Sandbox Code Playgroud)

似乎我删除了片段,它仍然是活跃的... 为什么?如何取消激活片段?

Ass*_*iel 150

读取setArguments(Bundle args)源代码将帮助您理解:

/**
* Supply the construction arguments for this fragment.  This can only
* be called before the fragment has been attached to its activity; that
* is, you should call it immediately after constructing the fragment.  The
* arguments supplied here will be retained across fragment destroy and
* creation.
*/
public void setArguments(Bundle args) {

    if (mIndex >= 0) {
        throw new IllegalStateException("Fragment already active");
    }
    mArguments = args;
}
Run Code Online (Sandbox Code Playgroud)

您不能在同一片段的代码中再次使用setArguments(Bundle args).您想要做的是我想要创建一个新的片段并再次设置参数.或者您可以使用getArguments()然后使用bundle 的方法来更改其值. put

  • +1表示"你可以使用getArguments()然后使用bundle的put方法来改变它的值." (53认同)
  • `getArguments().putAll(bundle);`将覆盖整个bundle (25认同)
  • @ Leem.fin:你能接受这个答案吗? (3认同)
  • `getArguments().putAll(bundle);`不覆盖整个包.在调用此密钥后,我仍然拥有我之前的密钥和值.在我的例子中,我使用了`getArguments().clear();`并清理了Arguments. (2认同)

War*_*zit 1

尝试在添加新片段之前删除上一个片段:/sf/answers/438630111/