Android 在两个固定片段之间切换
我有一个活动,运行一个异步任务来收集一系列数据。这些数据可以用几种方式表示,为了简单起见,假设有两种方式。我希望用户能够在这两种表示(listview和graphical view)之间切换 所以我用ListFragment和GraphicFragment创建了一个FragmentActivity 如何在这两者之间切换,以便用户可以来回切换?我尝试使用replace,但是前面的片段被破坏了,这不符合我的兴趣,因为它的引用有我的活动传递的数据。(即,我不希望每次用户在视图之间切换时都重新创建片段) 我也试过隐藏和显示,但我无法让它工作,其中一个片段没有显示 另外,当我旋转时,我猜碎片会被破坏,因为我在尝试访问它们时会得到一个nullpointerexceptionAndroid 在两个固定片段之间切换,android,fragment,Android,Fragment,我有一个活动,运行一个异步任务来收集一系列数据。这些数据可以用几种方式表示,为了简单起见,假设有两种方式。我希望用户能够在这两种表示(listview和graphical view)之间切换 所以我用ListFragment和GraphicFragment创建了一个FragmentActivity 如何在这两者之间切换,以便用户可以来回切换?我尝试使用replace,但是前面的片段被破坏了,这不符合我的兴趣,因为它的引用有我的活动传递的数据。(即,我不希望每次用户在视图之间切换时都重新创建片段)
@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;
}
旋转屏幕后,我得到一个NullPointerException
此外,在切换fragmenents时,其数据不会更新(即,我从list fragment开始,它显示正确的数据,然后切换到graphic,不显示数据,切换回list,再次无数据)。如果使用
setRetainInstance时字段为空(true)代码>,然后在活动中重新创建它们(片段)。确保在活动中的onSaveInstanceState()
中设置了某些内容,以便在onCreate()
中,savedInstanceState
将不为空,甚至可以是空包或无用变量,例如:
@Override
public void onSaveInstanceState(Bundle outstate){
super.onSaveInstanceState(outstate);
outstate.putBoolean("stateChanged", true);
}
确保在添加参数之前调用super
另一方面,我个人从未将片段存储在数组中。我在活动中使用FrameLayout
作为片段容器,就像您一样,如果需要更新某些内容,我只需调用:getSupportFragmentManager().findffragmentbyid(R.id.fragment_container).setWhatINeed()代码>这样我总能得到可见的片段
让我知道更新的进展情况,我会尽我所能更新这篇文章。你真的应该添加一些代码,这样人们就能更好地帮助你。如果不希望片段被销毁,请调用setRetainInstance(true)代码>在片段的onCreate
中。然后在您的活动中使用replace
。我发布了我的oncreate函数和我切换碎片的代码部分。您应该查看碎片生命周期,这就是您的问题生效的地方。当您旋转屏幕时,活动将被销毁并重新创建,这反过来又会销毁片段。如果设置setRetainInstance(true)代码>在片段中,所有信息(变量)仍将具有值,但您需要重新创建视图,因为它们将被销毁。我将对此进行查看,但我尝试使用SetRetaintSance,在旋转屏幕时,我的第一个片段和第二个片段字段将为空。setRetainInstance
对您没有帮助,由于您的字段firstFragment
等位于您的活动中,该活动已被销毁并重新创建,因此其字段现在为空。碎片仍然存在,但你需要找到它们。您需要将这样的代码添加到活动的onCreate:FragmentManager fm=getFragmentManager();firstFragment=fm.findFragmentByTag(您的_FRAGMENT_标记)代码>更多详细信息,请尝试,但没有乐趣。我之所以在数组中执行此操作,是因为这些片段是主要活动的观察者,因此当新数据到达时,它们都会同时收到通知。您现在遇到的具体问题是什么?还是和以前一样吗?几个问题:1)您是否检查以确保方向更改时savedInstanceState
不为null(即,如果(savedInstanceState==null)
,则在之后放置log.d
)
?2)您是否删除了addToBackStack(null)
调用?您可能会得到一个空指针,因为您正在将first/secondFragment的本地实例添加到Backback中,然后尝试更新它,我认为这是不可能的(无法更新堆栈上的项)@MichelReap-而不是将片段放入数组中,使用标记创建它们,并将标记放入数组中。然后,您可以使用findFragmentByTag
随时获取它们的当前实例-不再担心配置更改或应用程序中断后过时的引用。
@Override
public void onSaveInstanceState(Bundle outstate){
super.onSaveInstanceState(outstate);
outstate.putBoolean("stateChanged", true);
}