簡體   English   中英

屏幕旋轉時的片段視圖狀態

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM