我有一个活动,包含片段'list',点击其中一个项目后会将其自身替换为'content'片段。当用户使用后退按钮时,他再次被带到“列表”片段 问题是片段处于默认状态,无论我尝试保留数据。
事实:
public static TheFragment newInstance(Bundle args)
,setArguments(args)
和Bundle args = getArguments()
FrameLayout
内(即不是嵌套片段)setRetainInstance
,因为我的活动是主/详细信息流,在大屏幕上有2个窗格布局。 7英寸平板电脑有1个纵向画面和2个横向画面。如果我保留'列表'片段实例,它(我认为)将屏幕旋转搞乱FragmentTransaction#replace(int, Fragment, String)
显示,其ID相同但标签不同onSaveInstanceState(Bundle)
,但框架并没有始终,因为per the doc:“在很多情况下,片段可能主要是拆除(例如放置在没有显示UI的后台堆栈上),但在其拥有的活动实际需要保存其状态之前,其状态将不会被保存。“ 从上面的子弹5中,我猜想片段事务后需要恢复内存的低端设备可能会调用Fragment#onSaveInstanceState(Bundle)
。但是,在我的测试设备(Galaxy Nexus和Nexus 7)上,框架不会调用该方法。所以这不是一个有效的选择。
那么,我如何保留一些片段数据呢?传递给Fragment#onCreate
,Fragment#onActivityCreated
等的捆绑包始终是null
。
因此,我无法从全新的片段启动到后台堆栈恢复发挥作用。
答案 0 :(得分:10)
这似乎不对,但这就是我最终做的事情:
public class MyActivity extends FragmentActivity {
private Bundle mMainFragmentArgs;
public void saveMainFragmentState(Bundle args) {
mMainFragmentArgs = args;
}
public Bundle getSavedMainFragmentState() {
return mMainFragmentArgs;
}
// ...
}
在主要片段中:
public class MainFragment extends Fragment {
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = ((MyActivity) getActivity()).getSavedMainFragmentState();
if (args != null) {
// Restore from backstack
} else if (savedInstanceState != null) {
// Restore from saved instance state
} else {
// Create from fragment arguments
args = getArguments();
}
// ...
}
// ...
@Override
public void onDestroyView() {
super.onDestroyView();
Bundle args = new Bundle();
saveInstance(args);
((MyActivity) getActivity()).saveMainFragmentState(args);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveInstance(outState);
}
private void saveInstance(Bundle data) {
// put data into bundle
}
}
有效!
onDestroyView
onSaveInstanceState
setArguments
涵盖所有活动,并始终保留最新鲜的信息。
它实际上更复杂,它基于interface
,来自onAttach
/ onDetach
的侦听器未注册/注册。但原则是一样的。