所以我有一个附加到活动的片段,我试图确保在旋转屏幕时(或任何会中断活动的事情)顺利进行。为此,我在活动中使用onSaveInstanceState和onRestoreInstanceState方法来保存我的活动存储的信息。
当创建my片段的视图时,片段会询问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()始终最后调用。这意味着在创建视图时片段无法访问活动的信息。
这应该发生吗?在恢复活动时,如何让我的片段视图使用活动中的信息?
答案 0 :(得分:1)
更新回复:
阅读替代方案Passing data between a fragment and its container activity。另请参阅this。
之前的回复修订:
请参阅this并尝试将您的代码置于onResume()中,并使视图无效或detach/attach the fragment作为快速解决方案,但不是the best solution,正如Alex Lockwood所说:
片段是可重复使用的UI组件。他们有自己的生命周期, 显示自己的视图,并定义自己的行为。你通常 不需要让你的活动陷入内部困境 片段的运作,如片段的行为应该是 自包含且独立于任何特定活动。
如果您之前确实需要代码,请覆盖下一个方法并直接保存/恢复片段中所需的数据:
/**
* 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...;
}
创建这个,用于从bundle中检索所需的数据:
public void restoreInstanceState(Bundle savedInstanceState) {
... = savedInstanceState.get...
}
如果由于某种原因需要活动代码,请使用{p>或使用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()
方法添加到活动中。
答案 1 :(得分:1)
我认为最简单的方法是使用EventBus 您可以在重新创建活动时发送“msg”,并且您的片段的“目标方法”将获得此消息(msg是Object,它可以是一个包)。