[英]Handling Screen Rotation for Fragment inside of View(State)PagerAdapter inside Fragment
[英]Fragment View State on Screen Rotation
當用戶單擊列表中的項目時,我會加載一些片段。 假設用戶單擊了列表中的第二個項目,並加載了第二個片段。 但是,旋轉屏幕時,列表中的第一個片段將被加載。 每當用戶旋轉屏幕時,如何確保加載相同的片段。 這就是我加載片段的方式
private void selectItem(position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new FirstFragment();
break;
case 1:
fragment = new SecondFragment();
break;
case 2:
fragment = new ThirdFragment();
break;
default:
break;
}
if (fragment != null) {
android.app.FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
}
else {
Log.e("NavigationActivity", "Error in creating fragment");
}
}
我在活動的onCreate
中調用selectItem(0)
。
整個活動在輪換期間被銷毀並重新創建。 因此,如果您在Activity.onCreate中調用setItem(0),則始終在內容框架中獲得FirstFragment。
似乎簡單的事情可能只是檢測您是否已經在onCreate中設置了一個片段而不加載默認值。 使用onSaveInstanceState和/或將片段標記為保留。
我對保留的碎片或超出初始加載的碎片管理沒有太多經驗,因此僅使用onSaveInstanceState來跟蹤哪個已加載似乎合適。
在您的活動中,覆蓋onSaveInstanceState:
@Override
public void onSaveInstanceState(Bundle bundle)
{
bundle.putInt("which_fragment", _fragmentId);
super.onSaveInstanceState(bundle);
}
_fragmentId
只是您正在加載的特定片段的一些數字標識符。 甚至可能是布局ID。 在您的selectItem方法中設置此值。
然后在onCreate中:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
_fragmentId = 0;
if (savedInstanceState != null)
{
_fragmentId = savedInstanceState.getInt("which_fragment", 0);
}
...
selectItem(_fragmentId);
}
首先,我不會使用positionOnTheList->Fragment
依賴關系。 我將取決於一些id
(最終還是來自資源)。
其次,我認為當您從列表中選擇項目時,您不應該為每個Fragment
類創建新實例。
您應該考慮這種方法:
Fragment f = fragmentManager.findFragmentById( String.valueOf(id) );
if( f == null )
f = new FragmentDependingOnId();
mCurrentlySelectedId = id;
fragmentManager.beginTransaction()
.replace( R.id.container, f , String.valueOf(id))
.commit();
添加以下方法:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(SELECTED_ID, mCurrentlySelectedId);
}
並在onCreate
添加:
if(savedInstanceState!=null){
mCurrentlySelectedId = savedInstanceState.getInt(SELECTED_ID);
selectItem(mCurrentlySelectedId);
}
使用片段時,通常使用onCreateView
來增加布局。 然后,您使用onActivityCreated
來執行初始化listviews等所需的所有工作...
在您的情況下,您遇到的問題是您應該使用saveInstanceState來跟蹤是否加載了片段,因為該片段在每次旋轉時都會重新創建。
讓我們看一些代碼
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.your_fragment_layout, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
//do nothing if the state already exists
} else {
//do something if state already exists
}
}
請注意,如果您需要保存給定的值(例如布爾值),則可以使用
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(YOUR_BOOL_TAG, mYourBooleanVar);
}
並通過使用將其返回到onCreateView
中
mYourBooleanVar= savedInstanceState.getBoolean(YOUR_BOOL_TAG);
同樣適用於其他類型。
編輯
我沒有完全回答您的問題,因此我提出了更多細節。 上面的代碼在片段中。 但是對於您的問題,在activity
您需要類似的東西。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
//here is the transaction to load your first fragment
}
}
而且您的第一個片段不會每次都重新加載。
首次savedInstanceState
將為null,您將設置默認片段。 然后,每次旋轉savedInstanceState
都不為null,並且默認片段不會重新加載,而是當前存在的片段。
僅此代碼與您相關,但我讓EDIT上方的代碼對其他人有用,以防它們對他們有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.