2013-07-23 57 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()会被调用并偶然重新创建适配器。