隐藏的backstack片段在配置更改时重新显示

时间:2012-06-22 11:52:46

标签: android android-fragments screen-rotation

我正在构建一个活动多片段应用程序。每次交易后我都会添加到backstack。在几次隐藏和显示片段然后我旋转手机之后,容器上添加的所有片段都被恢复,每个片段都在另一个片段之上。

可能是什么问题?为什么我的活动会显示我之前隐藏的片段?

我正在考虑隐藏所有以前隐藏的现在显示的片段,但这样做有更“优雅”吗?

3 个答案:

答案 0 :(得分:9)

在每个片段上使用setRetainInstance(true),您的问题就会消失。
警告:将此设置为true将更改Fragments生命周期。
虽然setRetainInstance(true)解决了问题,但有时您可能不想使用它。 要解决此问题,请在Fragment上设置布尔属性并恢复可见性:

private boolean mVisible = true;
@Override
public void onCreate(Bundle _savedInstanceState) {
    super.onCreate(_savedInstanceState);
    if (_savedInstanceState!=null) {
        mVisible = _savedInstanceState.getBoolean("mVisible");
    }
    if (!mVisible) {
        getFragmentManager().beginTransaction().hide(this).commit();
    }
    // Hey! no setRetainInstance(true) used here.
}
@Override
public void onHiddenChanged(boolean _hidden) {
    super.onHiddenChanged(_hidden);
    mVisible = !_hidden;
}
@Override
public void onSaveInstanceState(Bundle _outState) {
    super.onSaveInstanceState(_outState);
    if (_outState!=null) {
        _outState.putBoolean("mVisible", mVisible);
    }
}

配置更改后(例如屏幕方向),实例将被销毁,但Bundle将被存储并注入新的Fragment实例。

答案 1 :(得分:2)

我遇到了同样的问题。你应该检查活动的onCreateView()函数中的源代码。

public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    if(savedInstanceState == null){//for the first time

        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        FragmentExample fragment = new FragmentExample();
        fragmentTransaction.add(R.id.layout_main, fragment);
        fragmentTransaction.commit();

    }else{//savedInstanceState != null
        //for configuration change or Activity UI is destroyed by OS to get memory 
        //no need to add Fragment to container view R.id.layout_main again
        //because FragmentManager supported add the existed Fragment to R.id.layout_main if R.id.layout_main is existed.
        //here is one different between Fragment and View

    }
}

activity_main.xml中:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/layout_main">

答案 2 :(得分:0)

您可能想尝试使用replace()功能而不是隐藏和显示。当我开始使用Fragments并使用替换函数时,我遇到了同样的问题,这确实有助于更好地管理Fragments。这是一个简单的例子:

fragmentManager.replace(R.id.fragmentContainer, desiredFragment, DESIRED_FRAGMENT_TAG)                                   
               .addToBackStack(null)
               .commit();