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