就是这种情况。我在片段A中有一个列表视图,其中包含无限列表,当用户到达底部时,该列表将通过Web服务填充。
列表视图中的每个项目都有一个"查看更多"链接打开此项目的详细片段B.
我使用FragmentManager.replace()方法和" addToBackStack"。 (我' m"替换"而不是"添加"因为我在片段A中有菜单项,我不想在片段B中显示。我已经尝试了不同的添加片段的方法,而不是在打开已经工作的片段B时删除并尝试隐藏菜单项,但在其他一些问题中结束,所以我更喜欢使用replace")
说明用户正在查看列表中的第25项,然后打开详细信息片段。当用户然后点击后退按钮时,我希望用户继续完全查看相同位置的列表。
这很容易用"添加片段"而不是"取代"因为片段从未被删除。当使用"替换"该片段被删除,然后在回击时它将再次渲染(也就是说,将再次调用onCreateView)
但此时,已经为片段创建了视图,因为FragmentManager.remove仅从视图层次结构中删除视图,但不要销毁该片段。所以我理论上"可以做这样的事情:
if(view == null){
//Create view
view = (ViewGroup) inflater.inflate(R.layout.news_list, container, false);
}
return view;
但在这种情况下,它将导致
java.lang.IllegalStateException:指定的子节点已经有了 家长。您必须先在孩子的父母身上调用removeView()。
所以,我的解决方案如下:
if(view == null){
view = (ViewGroup) inflater.inflate(R.layout.news_list, container, false);
} else {
((ViewGroup) view.getParent()).removeView(view);
}
return view;
这对我有用,但我不知道是否会有一些"隐藏"超出此解决方案的错误,我现在没有看到。
我想听听你的意见。提前致谢
答案 0 :(得分:0)
为什么不记住用户滚动的位置onPause片段并将列表视图位置设置为onResume中的滚动位置?只是一个想法,我不确定您的解决方案是否有任何不利影响/错误。
@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
try{
index = this.getListView().getFirstVisiblePosition();
View v = this.getListView().getChildAt(0);
top = (v == null) ? 0 : v.getTop();
}
catch(Throwable t){
t.printStackTrace();
}
在片段的onResume上:
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
/**
* Check to see if there is any scroll position
* saved up, this is done in case of user returning
* back from the contact detail screen
*/
setListAdapter(adapter);
if(index!=-1){
this.getListView().setSelectionFromTop(index, top);
}
}
希望这有帮助!
答案 1 :(得分:0)
如果在执行删除片段的事务时未调用addToBackStack(),则在提交事务并且用户无法导航回到该片段时,该片段将被销毁。然而,如果您在删除片段时调用addToBackStack(),则片段将停止,并且如果用户导航回来,将会恢复该片段。
提示:对于每个片段事务,您可以应用转换 动画,通过在提交之前调用setTransition()。
调用commit()不会立即执行事务。相反,它会在线程能够执行时将其安排在活动的UI线程(“主”线程)上运行。但是,如果需要,您可以从UI线程调用executePendingTransactions()以立即执行commit()提交的事务。除非事务是其他线程中作业的依赖项,否则通常不需要这样做。