7

我有一个使用Fragments 的选项卡式应用程序,还有一个小问题。

MainActivity(extends FragmentActivity- 除了布局规范之外没有代码) 在其布局中onCreate包含一个Fragment被调用的TabsFragment(extends Fragment, implements OnTabChangeListener) (将选项卡本身包含在 a 中),使用sFrameLayout切换 sub - s。FragmentTransaction

后一个子Fragments是具有实际内容的子,当用户转动设备、访问另一个应用程序、接听电话或做其他事情时,我希望保存其状态。目前,sub- Fragments 的状态没有被保存,但活动会记住Fragment正在显示的 sub-s。(因此,如果我将设备置于横向模式并在选项卡 3 处于活动状态时转动设备,则选项卡 3 将以纵向模式出现,重置,但显示。因此在我没有做任何事情的情况下保留了某些状态)。

因为我有多种布局(横向和纵向),android:configChanges="orientation"所以在清单中不是一个选项 - 我不想使用它,因为它是一个美化的创可贴。

我正在使用 v4 支持库(第 10 版),在搜索 API 之后,我遇到FragmentManager.saveFragmentInstanceState()Fragment.setInitialSavedState(Fragment f). 我已将每个 sub- 的 saveFragmentInstanceState( Fragment)onPause()放在TabsFragment. 我不确定这是否有效,因为无论我放在哪里setInitialSavedState,它都会给出IllegalStateException- 但即使我刚刚初始化了一个新的子Fragment选项卡也会发生这种情况。当我将它放入时它也会onResume崩溃TabsFragment

代码片段:

//... this is the 'showTab' method
if(getFragmentManager().findFragmentByTag(id) == null)
{
  Fragment f = null;
  if(BASIC_TAB.equals(id))
  {
    f = new BasicTabFragment();
    f.setInitialSavedState(basicState); // basicState was set in onPause()
    getFragmentManager().beginTransaction().replace(tabNo, f, tabID).commit();
  }
}

如果将类似的代码放在 中onResume,我会收到以下错误:

错误片段: FATAL EXCEPTION: main java.lang.RuntimeException: Unable to resume activity (org.example.App/org.example.App/MainActivity): java.lang.IllegalStateException: Fragment already active

-snip-

Caused by: java.lang.IllegalStateException: Fragment already active at  android.support.v4.app.Fragment.setIniailSavedState(Fragment.java:507)
at org.example.App.TabsFragment.onResume(TabsFragment.java:223)

等等

显然,我在生命周期的错误时间点调用了 setInitialSavedState,但我不清楚何时应该发生这种情况。

此外,鉴于选项卡式设置的复杂性,我开始怀疑 FragmentManager.saveFragmentInstanceState() 是否确实是在这里使用的最佳选择。如果是这样,用什么?如何保存应用程序选项卡的状态?

4

1 回答 1

2

当 Activity 被销毁时,Fragment 会从 Activity 中分离出来,并在重新创建时重新附加。因此,片段应该仍然以其当前状态存在。重新连接时,OnCreateView再次调用。如果您像从头开始一样初始化所有内容(即将列表设置为new ArrayList()),您将清除片段的状态。

尝试在 Fragment 中为需要保留的所有内容创建一个实例变量(即,任何文本字段的字符串 - EditText 字段将按照您的提及自动保存)。例子:

字符串文本;
文本视图电视;

公共视图 onCreateView(LayoutInflater i, ViewGroup vg, Bundle b)
{
   // 这将重新膨胀布局中的所有内容。如果您在此处初始化任何文本字段,它会将它们重置为您在 xml 文件中设置的值
   查看 v = i.inflate(R.layout.myLayout, vg, false);

   如果(文本!= null)
       tv.setText(文本);
}

text当您的 TextView 值更改时(例如在 OnClickListener 或类似中),除了您使用它执行的任何其他操作之外,还设置 的值。当片段被重新附加时,它会将其设置为最后一次所做的更改。

于 2013-01-04T09:53:24.577 回答