Android:恢复后退栈中的片段实例状态

5

你好,我有一个活动,其中包含两个片段。

  1. 片段A
  2. 片段B

    • 片段A具有EditText和ListView。
    • 一旦我在EditText中输入内容并按下Enter,就会填充ListView。
    • 现在,片段A的ListView已经填充了数据。
    • 单击片段A的ListView上的任何项都将向用户发送片段B。
    • 此时,我正在使用片段B替换片段A。
    • 因此,当用户点击返回按钮时,他会返回到片段A。

现在的问题是,如果用户在片段B中,并且发生屏幕旋转等配置更改超过一次,则我的ListView为空,因为我的arraylist为null。

请注意,我在片段A和片段B中都使用了onSavedInstanceState。如果我的当前片段是片段A,并且发生配置更改,则还原状态没有问题,因为在onCreateView中,我从bundle获取arraylist。

我知道当我从片段B回到先前在backstack中的片段A时,我的arraylist为null的原因是什么。当片段A在backstack中时,唯一被调用的方法是onSaveInstanceState,因此在第一次配置更改后,我的arraylist字段为null,因为我无法将保存在savedInstanceState bundle中的arraylist分配给arraylist字段。

我不想在清单文件中使用android:configchanges属性。

我的问题是如何还原在backstack中的片段的状态。


只需将您的ArrayList存储在onSavedInstance()方法中。然后在onCreateView()方法中检查如果onSavedInstance不为空,则只需检索您的ArrayList即可。 - Piyush
1
在调用 onStart() 方法时,请先检查您的 ArrayList 是否为 null,然后再设置适配器。 - Piyush
@PiyushGupta 但是还有一个问题,当我在片段B中旋转手机两次时,片段A中的ArrayList变成了null。 - krishna
1
在您的活动清单文件中使用 ConfigChanges = "screenSize|keyBoardHidden|orientation"。 - Piyush
这将防止在配置更改时重新加载数据。而片段是活动的一部分,因此我们无法在清单文件中注册它。因此,我们需要将该权限应用于创建片段的特定活动!! - Piyush
显示剩余3条评论
3个回答

2

我已经阅读了您的情况。基本上,当您将arraylist添加到fragment的savedinstanceState中时,您正在做正确的工作,但在我的看法中,您在activity中犯了一个小错误。

当方向更改时,Activity会调用onDestroy,然后再调用onCreate。在这种情况下,如果您没有检查您的fragment是否已经添加,它就会用新的fragment替换它。

以下是您应该在onCreate()中加入的代码:

 FragmentManager fragmentManager = getFragmentManager();
    Fragment fragment = fragmentManager.findFragmentByTag("FragmentA");
    if(fragment==null){
        fragmentManager.beginTransaction().add(R.id.container, new FrgamentA(), "FragmentA").commit();
    }

另外一个要点是,当您想保留第一个片段时,请添加以下内容:
setRetainInstance(true);

在片段的onCreate中。

请在GitHub上查找此演示inpulse-fragment

在此演示中,当您增加计数器时,它将显示在上面的文本视图中,如果您单击该文本视图,则将导航到片段B。现在您可以尝试旋转。 如有任何疑问,请告诉我。


setRetainInstance(true); 对我来说不起作用,因为我希望片段能够重新创建,并且使用setRetainInstance(true)将无法重新创建片段。此外,我在MainActivity的onCreate中添加了类似的代码。我通过在MainActivity中保存后退堆栈片段的状态来解决了这个问题。谢谢你的回答。 - krishna

2

我通过在将Fragment添加到backstack之前将其所有细节传递给主Activity并将状态保存在主Activity的savedInstance状态中,实现了保留Fragment状态的目标。每当backstack更改并且先前的Fragment可见时,我会从主Activity向其传递该Fragment的保存实例状态,以此来保留状态。我不确定这是否是正确的方法。


1
你可以在onAttach中使用setRetaininstance(true),并在活动清单文件中添加此行ConfigChanges = "screenSize|keyBoardHidden|orientation"

Vikram,我在问题中提到,我不想在配置更改时停止活动并重新创建它。因此,使用ConfigChanges无法实现目标。 - krishna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接