具有多个片段和屏幕方向的单个活动

时间:2014-06-26 00:57:12

标签: android android-fragments screen orientation handle

我目前正在处理Android和Android的问题。它在屏幕旋转时的重新创建周期:

我有一个Activity和许多片段(Support-V4)。 例如,在带有片段的单个活动上登录它,当登录然后应用程序改变它的导航行为并使用多个片段时,我这样做,因为在片段A之间传递数据到片段B它比在活动A和活动B之间传递数据容易得多。

所以当我旋转设备时出现了我的问题,在我的第一个方法中,初始片段被加载了,但如果用户在第15页上旋转它会发生什么?&# 39; s设备,它将返回到Fragment 1并提供非常糟糕的用户体验。我将所有片段设置为保留其实例,并将其添加到Create:

上的MainActivity上
@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();
    }
}

现在,在屏幕方向改变后没有加载第一个片段,但是如果我尝试进行片段事务,则说明在onSaveInstanceState()之后无法执行FragmentTransaction.commit(),是否存在一种方法来处理这个?或者我真的需要使用嵌入了片段的多个活动吗?

非常感谢!

EDITED 我忘了补充一点,这只发生在一个特定的片段......例如我有以下片段流:

AreaFragment -> WaiterSelectionFragment -> WaiterOptionsFragment.

如果我在 AreaFragment 并且我旋转设备,我仍然可以添加/替换片段,没有任何反应,没有错误它正在抛出。如果我在 WaiterSelectionFragment 上也没有发生错误。但是,如果我在 WaiterOptionsFragment 上发生了错误,那么它就会被抛出。 WaiterSelectionFragment 具有以下结构:

  1. 的LinearLayout
  2. FragmentTabHost
  3. FragmentTabHost内部有一些片段,而且它发生了错误。您可能想知道为什么FragmentTabHost?很容易,客户希望该应用程序显示TabBar,如果我使用原生Android选项卡,则选项卡会重新排列到 ActionBar 景观位置。

    编辑2

    我已经使用了@AJ Macdonald提供的方法,但到目前为止还没有运气。 我将当前片段保存为onSaveInstanceState(Bundle)方法并在Android Activity上的onRestoreInstanceState(Bundle)方法上恢复我的片段,我恢复后退按钮和当前 片段 但当我到达第三个 片段 时,仍会出现错误。我使用的是包含4个片段的 ViewPager ,这会导致问题吗?仅在App的这一部分发生。我只有4个(主要工作流程)片段,在第一个,第二个和第三个片段上没有出现错误,仅在 ViewPager 部分。

2 个答案:

答案 0 :(得分:4)

为每个片段添加一个唯一标记。

在您的活动onSaveInstanceState中,存储当前片段。 (如果保留一个每次片段更改时自动更新的变量,这可能是最容易做到的。)

在您的活动的onCreateonRestoreInstanceState中,将标记从已保存的包中拉出并启动该类型的新片段。

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);
    }

答案 1 :(得分:0)

尝试使用FragmentTransaction.commitAllowingStateLoss()代替FragmentTransaction.commit()。这应该会停止抛出异常,但缺点是如果再次旋转设备,UI的最新状态可能不会返回。这是一个建议,因为我不确定使用FragmentTabHost的效果,如果它有任何影响。