我发现许多类似的问题,但不幸的是没有答案符合我的要求。
我有不同的布局为纵向和横向,我正在使用回栈,这两个都阻止我使用setRetainState()
和技巧使用配置更改例程。
我在TextView中向用户显示了某些信息,但这些信息不会保存在默认处理程序中。当我只使用Activities编写应用程序时,以下代码运行良好:
TextView vstup;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.whatever);
vstup = (TextView)findViewById(R.id.whatever);
/* (...) */
}
@Override
public void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putCharSequence(App.VSTUP, vstup.getText());
}
@Override
public void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
vstup.setText(state.getCharSequence(App.VSTUP));
}
对于Fragment
s,这只在非常特定的情况下才起作用,具体来说,可怕的断裂是替换一个片段,将其放入后栈,然后在显示新片段的同时旋转屏幕,从我的理解来看,旧片段在被替换时不接收对onSaveInstanceState()
的调用,而是以某种方式保持与Activity
的链接,并且该方法稍后在其View
已经不存在了,所以查找我的任何TextView
结果都会得到一个NullPointerException
。
此外,我发现在Fragment
s中保留对TextViews
的引用不是一个好主意,即使在Activity
s中也是可以的。在这种情况下,onSaveInstanceState()
实际上保存了状态,但如果在隐藏片段时旋转屏幕 * 两次 *,问题会再次出现,因为它的onCreateView()
不会在新示例中调用。
我考虑将onDestroyView()
中的状态保存到某个Bundle
类型的类成员元素中(实际上是更多的数据,而不仅仅是一个TextView
)并将其保存在onSaveInstanceState()
中,但还有其他缺点,主要是如果片段当前显示,则两个函数的调用顺序相反,所以我需要考虑两种不同的情况。一定有一个更干净和正确的解决方案!
7条答案
按热度按时间pbwdgjma1#
要正确保存
Fragment
的示例状态,应执行以下操作:**1.**在片段中,通过覆盖
onSaveInstanceState()
保存示例状态,并在onActivityCreated()
中恢复:2.还有要点,在练习中,您必须将片段的示例保存在
onSaveInstanceState()
中,并在onCreate()
中恢复。8e2ybdfx2#
这是一个非常古老的答案。
我不再为Android编写代码,因此不能保证最新版本的功能,也不会有任何更新。
这就是我现在使用的方法......它非常复杂,但至少它处理了所有可能的情况。如果有人感兴趣的话。
或者,也可以将passive
View
中显示的数据保存在变量中,并将View
仅用于显示它们,从而保持这两件事的同步。vlju58qv3#
在最新的支持库中,这里讨论的解决方案都不再是必要的了。你可以用你喜欢的
Activity
来玩你的FragmentTransaction
的片段。只要确保你的片段可以用id或者标签来标识。只要你不尝试在每次调用
onCreate()
时重新创建片段,片段就会自动恢复,相反,你应该检查savedInstanceState
是否不为空,并在这种情况下找到对创建片段的旧引用。下面是一个例子:
不过请注意,在恢复片段的隐藏状态时,当前存在bug。如果您在Activity中隐藏片段,则需要手动恢复此状态。
mrwjdhj34#
我只想给予我从Vasek和devconsole中得到的解决方案,它可以处理本文中提到的所有情况。这个解决方案还可以处理手机多次旋转而碎片不可见的特殊情况。
下面是我存储包的位置,以备将来使用,因为onCreate和onSaveInstanceState是在片段不可见时进行的唯一调用
由于destroyView在特殊的旋转情况下没有被调用,我们可以确定,如果它创建了状态,我们应该使用它。
这部分也一样。
现在这里是棘手的部分。在我的onActivityCreated方法中,我示例化了“myObject”变量,但是旋转发生在onActivity,并且没有调用onCreateView。因此,在这种情况下,当方向旋转不止一次时,myObject将为null。我通过重用保存在onCreate中的同一个bundle作为输出bundle来解决这个问题。
现在,只要使用savedState包就可以恢复状态
0sgqnhkj5#
感谢DroidT,我做了这个:
我意识到如果Fragment不执行onCreateView(),它的视图就不会示例化,所以,如果后栈上的Fragment没有创建它的视图,我就保存最后一次存储的状态,否则我就用我想要保存/恢复的数据构建我自己的bundle。
1)扩展此类:
2)在你的片段中,你必须有这个:
3)例如,您可以在onActivityCreated中调用hasSavedState:
sbtkgmzw6#
使用此:
zd287kbt7#