片段调用片段在屏幕旋转时失去状态

Fragment calling fragments loosing state on screen rotation

您好,我创建了一个带有默认 "Navigation Drawer Activity" 的项目。 所以我有一个带有片段的 MainActivity,菜单上的每个项目都被替换了。

其中一个菜单是 "Customers",其中显示了客户列表。

从客户片段我可以看到这个客户的兴趣,有一个调用兴趣(InterestsListFragment)的片段(CustomerListFragment)。

还有更多的关卡,但要简短就够了。

这是 MainActivity 上的代码,我用它从片段调用片段并在它们之间传递数据

public void passData(Object[] data, Fragment f) {
    Bundle args = new Bundle();
    args.putSerializable("PASSED_DATA", data);
    f.setArguments(args);
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction()
            .replace(R.id.container, f)
            .addToBackStack("")
            .commit();
}

我用的是:

mCallbacks.passData(new Object[]{c}, new OpportunityListFragment());

问题是,当我从 activity 的哪个级别旋转 phone 时,它会返回到第一个片段(CustomerListFragment),如果我单击 "Back" 在单元格 phone 上它回到我旋转 phone 时的位置。

我该怎么做才能避免这种问题?如果我正在替换片段,为什么它会回到第一个 activity 唤起?

当您更改屏幕方向时,您的父级 Activity 将被销毁并重新创建。除非您以某种方式坚持关卡结构,否则它将始终显示为您第一次启动 activity 时的样子。您可以使用 bundle 对象,或者对于需要将其持久保存到数据库的更复杂的对象。

无论哪种方式,onSaveInstanceState 都是您的朋友。然后在您的 onCreate 方法中,您需要检查包或数据库,并相应地设置片段。

ste-fu 的回答是正确的,但让我们以编程方式进行探索。 Google 文档 @ Handling Runtime Changes 中有一个很好的工作代码。您必须执行 2 个代码片段。

1) 代码片段:

public class MyActivity extends Activity {

private RetainedFragment dataFragment;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // find the retained fragment on activity restarts
    FragmentManager fm = getFragmentManager();
    dataFragment = (DataFragment) fm.findFragmentByTag(“data”);

    // create the fragment and data the first time
    if (dataFragment == null) {

注意:代码使用 FragmentManager 查找当前 Fragment。如果 fragment 为 null,则 UI 或 app 尚未执行。如果不为空,则可以从 RetainedFragment 对象获取数据。

2) 需要保留Fragment状态

public class RetainedFragment extends Fragment {

// data object we want to retain
private MyDataObject data;

// this method is only called once for this fragment
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // retain this fragment
    setRetainInstance(true);
}

注意:setRetainInstance在OnCreate中使用。建议对 Fragment 进行子类化,将其命名为 RetainedFragment,用于片段 1。