[英]onCreateView() for Fragment being called before Activity onRestoreInstanceState()
因此,我在活动上附加了一个片段,我试图确保屏幕旋转时(或会中断活动的任何事物)顺利进行。 为此,我在活动中使用onSaveInstanceState和onRestoreInstanceState方法来保留活动中存储的信息。
创建我的片段的视图时,片段会向Activity询问信息(这在片段的onCreateView()中):
ArrayList<String> picList = mListener.getPics();
ArrayList<String> descripList = mListener.getDescriptions();
为了使该片段创建视图,它需要访问picList和descripList,它们是活动的成员变量。 这些成员变量在onSaveInstanceState和onRestoreInstanceState中存储和恢复。
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if(photoFile != null)
outState.putString("photoFile", photoFile.getAbsolutePath());
outState.putString("currentFragTag", currentFragTag);
outState.putStringArrayList("picList", picList);
outState.putStringArrayList("descripList", descripList);
}
@Override
protected void onRestoreInstanceState(Bundle saved) {
super.onRestoreInstanceState(saved);
if(saved.getString("photoFile") != null)
photoFile = new File(saved.getString("photoFile"));
currentFragTag = saved.getString("currentFragTag");
picList = saved.getStringArrayList("picList");
descripList = saved.getStringArrayList("descripList");
currentFrag = getFragmentManager().findFragmentByTag(currentFragTag);
changeFrag(currentFrag, currentFragTag);
}
问题是,在活动中调用onRestoreInstanceState()之前先调用onCreateView()。 我尝试在片段中使用onActivityCreated(),但在onRestoreInstanceState()之前也曾调用过它。 附加了调试器后,旋转屏幕时,始终会最后调用onRestoreInstanceState()。 这意味着在创建视图时,该片段无法访问活动的信息。
这应该发生吗? 恢复活动时,如何让片段的视图使用活动中的信息?
更新的响应:
阅读其他选择在片段及其容器活动之间传递数据 。 另请参阅此 。
先前的回应已修订:
看到这个并尝试将您的代码放在onResume()中并使视图无效或分离/附加该片段 ,这是一种快速解决方案,但不是Alex Lockwood所说的最佳解决方案 :
片段是可重用的UI组件。 他们有自己的生命周期,显示自己的观点,并定义自己的行为。 通常,您不需要使Activity混乱于Fragment的内部工作,因为Fragment的行为应该是独立的,并且与任何特定的Activity无关。
如果您之前确实需要代码,请覆盖下一个方法,然后直接在片段中保存/还原所需的数据:
/**
* Called when the fragment's activity has been created and this
* fragment's view hierarchy instantiated. It can be used to do final
* initialization once these pieces are in place, such as retrieving
* views or restoring state. It is also useful for fragments that use
* {@link #setRetainInstance(boolean)} to retain their instance,
* as this callback tells the fragment when it is fully associated with
* the new activity instance. This is called after {@link #onCreateView}
* and before {@link #onViewStateRestored(Bundle)}.
*
* @param savedInstanceState If the fragment is being re-created from
* a previous saved state, this is the state.
*/
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
restoreInstanceState(savedInstanceState);
}
}
/**
* Called to ask the fragment to save its current dynamic state, so it
* can later be reconstructed in a new instance of its process is
* restarted. If a new instance of the fragment later needs to be
* created, the data you place in the Bundle here will be available
* in the Bundle given to {@link #onCreate(Bundle)},
* {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}, and
* {@link #onActivityCreated(Bundle)}.
*
* <p>This corresponds to {@link Activity#onSaveInstanceState(Bundle)
* Activity.onSaveInstanceState(Bundle)} and most of the discussion there
* applies here as well. Note however: <em>this method may be called
* at any time before {@link #onDestroy()}</em>. There are many situations
* where a fragment may be mostly torn down (such as when placed on the
* back stack with no UI showing), but its state will not be saved until
* its owning activity actually needs to save its state.
*
* @param outState Bundle in which to place your saved state.
*/
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.put...;
}
并创建一个,用于从包中检索所需的数据:
public void restoreInstanceState(Bundle savedInstanceState) {
... = savedInstanceState.get...
}
或使用getActivity()
方法直接从此处访问某些方法或字段(如果出于某种原因需要活动代码)。
/**
* Return the {@link FragmentActivity} this fragment is currently associated with.
* May return {@code null} if the fragment is associated with a {@link Context}
* instead.
*/
final public FragmentActivity getActivity() {
return mHost == null ? null : (FragmentActivity) mHost.getActivity();
}
例如: ((YourActivity) getActivity()).getPics();
并将getPics()
方法添加到活动中。
我认为最简单的方法是使用EventBus。
您可以在重新创建活动时发送“ msg”,并且片段的“ target方法”将获取此msg(msg是Object,可以是一个包)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.