java 如何保存具有列表视图的片段状态
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17810749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to save state of Fragment having listview
提问by saikat
Here is a situation. I want to navigate from Fragment A-> B-> C.
这是一种情况。我想从片段 A-> B-> C 导航。
In B Fragment there is listview. On item click I open the detail view C Fragment. Ofcourse I used replace method and added addtoBackStack(null) while transactiong from B to C so that on Back press it returned to B.
在 B 片段中有列表视图。在项目上单击我打开详细视图 C 片段。当然,我使用了替换方法并添加了 addtoBackStack(null) 而从 B 到 C 的事务处理,以便在返回时它返回到 B。
All goes well. But when I return to B from C, the view is being refreshed and hence the webservice is being called again. I don't want to do this. I want to retain the B Fragment state with listview.
一切顺利。但是当我从 C 返回到 B 时,视图正在刷新,因此 webservice 被再次调用。我不想这样做。我想用列表视图保留 B 片段状态。
I got some post of Retain Instance, but it didn't help that much.
我收到了一些 Retain Instance 的帖子,但它并没有多大帮助。
Any help is much appreciated.
任何帮助深表感谢。
Thanks.
谢谢。
回答by alex
As explained hereyou can use onSaveInstanceState() to save data in the Bundle and retrieve that data in the onRestoreInstanceState() method.
如此处所述,您可以使用 onSaveInstanceState() 将数据保存在 Bundle 中,并在 onRestoreInstanceState() 方法中检索该数据。
Often setRetainState(true) is mentioned as way to keep the ui state in fragment, but it does not work for you because you are using the backstack.
经常提到 setRetainState(true) 作为将 ui 状态保持在片段中的方法,但它对您不起作用,因为您正在使用 backstack。
So a good way for you could be to save the scrollposition in onSaveInstanceState() and restore it in onRestoreInstanceState() like this:
所以对你来说一个好方法可能是在 onSaveInstanceState() 中保存滚动位置并在 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);
}
}
Further more you can find a more detailed similiar example here.
此外,您可以在此处找到更详细的类似示例。
回答by Tin Tran
I have solved this problem by creating my Adapter on onCreate() instead of onCreateView().
我通过在 onCreate() 而不是 onCreateView() 上创建我的适配器解决了这个问题。
This is because (I think) the fragment that is added to the backstack lost its View and then it has to recreate the view. onCreateView() get called and incidentally recreate your adapter.
这是因为(我认为)添加到 backstack 的片段丢失了它的视图,然后它必须重新创建视图。onCreateView() 被调用并顺便重新创建您的适配器。
回答by lingyfh
you can save define your ui in oncreate. when in onCreateView, only add it the layout. so the view state can save perfect.
您可以在 oncreate 中保存定义您的 ui。在 onCreateView 中时,只将其添加到布局中。所以视图状态可以保存完美。
this is my sv:
这是我的 sv:
in 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);
strong textin onCreateView
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));
回答by tyeen
I think you can save your ListView's position just before you're leaving fragment B. Maybe do that in fragment B's onStop(). And when you go back, you can fetch that position and restore it to ListView, do that for example in fragment B's onStart(). The position data maybe saved at the Activity so it won't be lost even the fragment detached.
我认为您可以在离开片段 B 之前保存 ListView 的位置。也许可以在片段 B 的onStop() 中这样做。当您返回时,您可以获取该位置并将其恢复到 ListView,例如在片段 B 的onStart() 中执行此操作。位置数据可能会保存在 Activity 中,因此即使片段分离也不会丢失。
One thing should be noticed that(I've been trapped by this), if the saved position data is updated by the background service, you should avoid restoring it to ListView before the life-cycle stage onStart()of fragment B, because actually, the framework will save the view's state just before leaving the fragment and restore it when get back. So if you restore your position before the framework do that, the framework's restore data will override yours.
需要注意的一点是(我已经被这个困住了),如果保存的位置数据被后台服务更新了,你应该避免在片段B的生命周期阶段onStart()之前将其恢复到ListView ,因为实际上,框架将在离开片段之前保存视图的状态,并在返回时恢复它。因此,如果您在框架执行此操作之前恢复您的位置,则框架的恢复数据将覆盖您的位置。