繁体   English   中英

在Activity onRestoreInstanceState()之前调用Fragment的onCreateView()

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM