2013-07-23 54 views
12

這是一種情況。我想從Fragment A-> B-> C導航。如何保存帶有列表視圖的片段狀態

在B片段中有listview。在項目上單擊我打開細節視圖C片段。 當然我使用替換方法,並添加了addtoBackStack(空),而從B到C的transactiong,以便在後退按下它返回到B.

一切順利。但是當我從C返回到B時,視圖正在刷新,因此Web服務被再次調用。我不想這樣做。我想用listview保留B片段狀態。

我收到了一些保留實例的帖子,但它沒有那麼多幫助。

任何幫助,非常感謝。

謝謝。

+0

你看過使用'Bundle'和Overriding'onSavedInstance()'嗎? – BC2

+0

Hi @ dakshbhatt21,你是否爲你的問題得到了解決方案??我有同樣的問題,它一直在困擾着我一個星期沒有突破。 –

+0

hi @mungaihkamau請檢查這篇文章http://developer.android.com/training/implementing-navigation/index.html,你可以找到各種類型的導航時,使用片段,只是檢查出來,讓我知道。 – dakshbhatt21

回答

12

如解釋here您可以使用onSaveInstanceState()將數據保存在Bundle中並在onRestoreInstanceState()方法中檢索該數據。

經常提到setRetainState(true)是爲了讓ui狀態保持片段狀態,但它不適用於您,因爲您正在使用backstack。

所以你一個好辦法可以挽救的onSaveInstanceState在()中的scrollPosition,它在onRestoreInstanceState恢復()這樣的:

public class MyListFragment extends ListFragment { 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 

    int index = this.getListView().getFirstVisiblePosition(); 
    View v = this.getListView().getChildAt(0); 
    int top = (v == null) ? 0 : v.getTop(); 

    outState.putInt("index", index); 
    outState.putInt("top", top); 
} 

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    [...] 
    if (savedInstanceState != null) { 
     // Restore last state for checked position. 
     index = savedInstanceState.getInt("index", -1); 
     top = savedInstanceState.getInt("top", 0); 
    } 
    if(index!=-1){ 
    this.getListView().setSelectionFromTop(index, top); 
    } 

} 

進一步,你可以找到更詳細的similiar例如here

+1

+1它確實工作得很好:) –

+0

@alex它不適合我。我在搜索按鈕(底部欄按鈕)列表視圖。當我點擊下面的搜索按鈕時,我的列表視圖將被重新創建。我無法保存listview的狀態。幫助我.. –

+0

你可以請張貼你的XML佈局並顯示你的代碼。開始一個新問題可能會更好,這樣做並將此問題鏈接爲「相似」 – alex

0

你可以保存定義你的UI在創建。 在onCreateView時,只添加它的佈局。 所以視圖狀態可以保存完美。

這是我的SV:

在OnCreate中

LayoutInflater inflater = (LayoutInflater) 
      ctx.getSystemService(ctx.LAYOUT_INFLATER_SERVICE); 
    View view = inflater.inflate(R.layout.pulltorefreshgridview, null); 
    mPullRefreshGridView = (PullToRefreshGridView) view 
      .findViewById(R.id.listcate_pullrefresh_gridview); 

強大的文本 在onCreateView

if (rootView != null) ((LinearLayout)rootView).removeAllViews(); 
View v = inflater.inflate(R.layout.listcate_fragment, container, false); 
rootView = v; 


    ((LinearLayout) v).addView(mPullRefreshGridView, 
      new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.FILL_PARENT, 
        LinearLayout.LayoutParams.FILL_PARENT)); 
0

我認爲你可以保存你離開之前你的ListView的位置片段B. 也許這樣做在片段B的onStop()。當你回去時,你可以獲取該位置並將其恢復到ListView,例如在片段B的onStart()中執行此操作。 位置數據可能保存在活動中,因此即使片段已分離,它也不會丟失。

有一點需要注意的是(我已經被困本),如果保存的位置數據是由後臺服務更新,你應該避免它恢復到ListView控件的生命週期階段在onStart()之前的片段B,因爲實際上,框架將在離開片段之前保存視圖的狀態,並在返回時恢復它。所以如果你在框架之前恢復你的位置,框架的恢復數據將會覆蓋你的位置。

2

我已經通過在onCreate()而不是onCreateView()上創建適配器來解決此問題。

這是因爲(我認爲)添加到backstack中的片段丟失了View,然後必須重新創建視圖。 onCreateView()會被調用並偶然重新創建適配器。