我有这个活动,我运行一个收集一系列数据的asynctask。这些数据可以用几种方式表示,为了简单起见,我们可以说有两种方法。我希望用户能够在这两个表示之间切换(列表视图和图形视图)。
所以我用ListFragment和我的GraphicFragment创建了一个FragmentActivity。
如何在这两者之间切换,以便用户可以来回走动?我尝试使用替换,但之后的片段被销毁,这不是我感兴趣的,因为它的引用有我的Activity传递的数据。 (即我不希望每次用户在视图之间切换时都重新创建片段。)
我也试图隐藏并显示但是我无法让它工作,其中一个片段没有显示。
此外,当我旋转时,我猜这些碎片会被破坏,因为我在尝试访问它时会得到nullpointerexception。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
pBar = (ProgressBar) findViewById(R.id.analyzingProgress);
// However, if we're being restored from a previous state, then don't
// create the fragment again (please)
if (savedInstanceState == null) {
firstFragment = new DirListFragment();
secondFragment = new GraphViewFragment();
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, secondFragment).commit();
fragments= new ArrayList<IFragment>();
fragments.add(firstFragment);
fragments.add(secondFragment);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.listView){
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
/*transaction.hide(secondFragment);
transaction.show(firstFragment);*/
transaction.replace(R.id.fragment_container, firstFragment);
transaction.addToBackStack(null);
transaction.commit();
}
else if(item.getItemId() == R.id.graph){
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
/*transaction.hide(firstFragment);
transaction.show(secondFragment);*/
transaction.replace(R.id.fragment_container, secondFragment);
transaction.addToBackStack(null);
transaction.commit();
}
return true;
}
当我尝试访问片段字段以更新其数据时出现问题:
for(IMyFragment frag: fragments){
frag.updateData(data);
}
旋转屏幕后出现NullPointerException。
同样在切换碎片时,他们的数据不会更新(即我从列表片段开始,它显示正确的数据,然后切换到图形,没有显示数据,切换回列表,再没有数据。)
答案 0 :(得分:2)
如果使用setRetainInstance(true);
时字段为空,那么您将在活动中重新创建它们(片段)。确保您在活动onSaveInstanceState()
中设置内容,因此在onCreate()
中,savedInstanceState
不会为空,它甚至可以是空包或无用变量,例如:
@Override
public void onSaveInstanceState(Bundle outstate){
super.onSaveInstanceState(outstate);
outstate.putBoolean("stateChanged", true);
}
请确保在添加参数之前调用super。
另一方面,我个人从未将我的片段存储在数组中。我在我的活动中使用FrameLayout
作为片段容器,就像你一样,如果我需要更新我刚刚调用的内容:getSupportFragmentManager().findFragmentById(R.id.fragment_container).setWhatINeed();
这样我总是得到可见的片段。
让我知道更新的进展情况,我会用我能提供的任何信息更新这篇文章。