Android 具有多个片段和屏幕方向的单个活动
我目前正在处理安卓系统的一个问题&它在屏幕上的重新创建周期: 我有一个单一的活动和大量的片段(Support-V4)。 例如,登录它在一个带有片段的单个活动上,当登录时,然后应用程序更改其导航行为并使用多个片段,我这样做了,因为在片段a到片段B之间传递数据要比在活动a到活动B之间传递数据容易得多 所以我的问题是,当我旋转设备时,在我的第一种方法中,初始片段被加载,但是会发生什么,如果用户在第15页上旋转设备,它会返回到片段1,并提供非常糟糕的用户体验。我将所有片段设置为保留其实例,并在创建时将其添加到MainActivity上:Android 具有多个片段和屏幕方向的单个活动,android,android-fragments,screen,orientation,handle,Android,Android Fragments,Screen,Orientation,Handle,我目前正在处理安卓系统的一个问题&它在屏幕上的重新创建周期: 我有一个单一的活动和大量的片段(Support-V4)。 例如,登录它在一个带有片段的单个活动上,当登录时,然后应用程序更改其导航行为并使用多个片段,我这样做了,因为在片段a到片段B之间传递数据要比在活动a到活动B之间传递数据容易得多 所以我的问题是,当我旋转设备时,在我的第一种方法中,初始片段被加载,但是会发生什么,如果用户在第15页上旋转设备,它会返回到片段1,并提供非常糟糕的用户体验。我将所有片段设置为保留其实例,并在创建时将其
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
initBackStackManager();
initControllers();
mayDownloadData();
setTitle();
if(savedInstanceState == null){
addAreaFragment();
}
}
现在,第一个片段在屏幕方向更改后没有加载,但是如果我尝试进行片段事务,它会说无法执行FragmentTransaction.commit()在onSaveInstanceState()之后,,是否有方法处理此问题?或者我真的需要使用多个活动,其中嵌入一个片段
多谢各位
已编辑
我忘了补充,这只发生在一个特定的片段上。。。例如,我有以下片段流:
AreaFragment -> WaiterSelectionFragment -> WaiterOptionsFragment.
如果我在区域fragment中,并且我旋转设备,我仍然可以添加/替换片段,并且没有发生任何事情,不会抛出错误。如果我在WaiterSelectionFragment上,也不会发生错误。但是,如果我在waiteroptionfragment上,就会抛出错误。WaiterSelectionFragment具有以下结构:
在Android活动中,我将当前片段保存在
onSaveInstanceState(Bundle)
方法中,并在onRestoreInstanceState(Bundle)
方法中恢复我的片段,我恢复了我的后退按钮和当前的片段,但当我到达第三个片段时,错误仍然发生。我使用的包含4个片段,这会导致问题吗?只有在应用程序的这一部分发生。我有4个(主工作流)片段,在第一个、第二个和第三个片段上没有显示错误,仅在部分。给每个片段一个唯一的标记
在活动的存储实例状态中存储当前片段。(如果您保留一个变量,在每次片段更改时自动更新,那么这可能是最容易做到的。)
在活动的onCreate
或onRestoreInstanceState
中,从保存的捆绑中拉出标记,并启动该类型的新片段
public static final int FRAGMENT_A = 0;
public static final int FRAGMENT_B = 1;
private int currentFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//other stuff
if(savedInstanceState == null){
addAreaFragment();
currentFragment = FRAGMENT_A;
}else{
currentFragment = savedInstanceState.getInt("currentFragment");
switch(currentFragment){
case FRAGMENT_A:
addAreaFragment();
break;
case FRAGMENT_B:
addFragmentB();
}
}
}
// when you switch fragment A for fragment B:
currentFragment = FRAGMENT_B;
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("currentFragment", currentFragment);
super.onSaveInstanceState(savedInstanceState);
}
给每个片段一个唯一的标签 在活动的存储实例状态中存储当前片段。(如果您保留一个变量,在每次片段更改时自动更新,那么这可能是最容易做到的。) 在活动的
onCreate
或onRestoreInstanceState
中,从保存的捆绑中拉出标记,并启动该类型的新片段
public static final int FRAGMENT_A = 0;
public static final int FRAGMENT_B = 1;
private int currentFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//other stuff
if(savedInstanceState == null){
addAreaFragment();
currentFragment = FRAGMENT_A;
}else{
currentFragment = savedInstanceState.getInt("currentFragment");
switch(currentFragment){
case FRAGMENT_A:
addAreaFragment();
break;
case FRAGMENT_B:
addFragmentB();
}
}
}
// when you switch fragment A for fragment B:
currentFragment = FRAGMENT_B;
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("currentFragment", currentFragment);
super.onSaveInstanceState(savedInstanceState);
}
建议尝试使用
FragmentTransaction.commitAllowingStateLoss()
代替FragmentTransaction.commit()
。这应该可以阻止抛出异常,但缺点是如果再次旋转设备,UI的最新状态可能不会返回。这是一个建议,因为我不确定使用FragmentTabHost
是否有任何效果。一个尝试的建议是使用FragmentTransaction.commitAllowingStateLoss()
代替FragmentTransaction.commit()
。这应该可以阻止抛出异常,但缺点是如果再次旋转设备,UI的最新状态可能不会返回。这是一个建议,因为我不确定使用FragmentTabHost
的效果,如果它有任何效果的话。您在什么时候尝试提交事务?是在活动
生命周期回调期间,如onPause
或onStop
?不是,我有一个片段使用FragmentTabHost,当设备旋转时,它用网格显示片段,用户选择一个单元格,然后添加一个新片段,它在使用FragmentTransaction时不在该点。commit()您试图在什么时候提交事务?是在活动
生命周期回调期间,如onPause
或onStop
?不是,我有一个片段使用FragmentTabHost,当设备旋转时,它用网格显示片段,用户选择一个单元格,然后添加一个新片段,它在使用FragmentTransaction时不在该点。commit()我使用类名作为片段的标记。但是例如,为了启动片段B,它向vía传递了一个静态newInstance(…)方法的一些数据。如果你传递给片段B的数据是基元类型,你也可以尝试将它保存到savedInstanceState包中。我想不出任何简单的方法来处理非原始对象。我认为当活动被重新创建时,后台将会丢失。您可能能够将带有所有backbackback片段标记的ArrayList存储到bundle中。。。然后,在onCreate中,使用该列表