Android应用程序会丢失其碎片状态

时间:2013-07-05 04:13:48

标签: android overlay fragment tabbar

我的应用程序中有一个带有几个按钮的标签栏,对于那些按钮,有一个片段。单击按钮时,我隐藏当前显示的一个,然后显示与单击按钮对应的片段。一切都很好,但有时当我从另一个活动返回或在背景中使用应用程序更长时间时,我会看到所有这些碎片叠加在自己身上。

这种行为的原因是什么?我该如何解决?

更新1:

这是我如何使用恢复实例状态

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    mCurrentTab = 0;

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

    if (fragment1 != null)
        ft.show(fragment1);
    if (fragment2 != null)
        ft.hide(fragment2);
    if (fragment3 != null)
        ft.hide(fragment3);
    if (fragment4 != null)
        ft.hide(fragment4);
    if (fragment5 != null)
        ft.hide(fragment5);

    ft.commit();
}

这里是在onTabbarButtonClick中切换片段(所有按钮都有相同的监听器)

@Override
public void onClick(View v) {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

    // hide only what is needed and when it is needed
    // for example when user clicks currently selected tab then nothing is done
    switch (mCurrentTab) {
    case 1:
        if (v.getId() != R.id.btn1)
            ft.hide(fragment1);
        break;
    case 2:
        if (v.getId() != R.id.btn2)
            ft.hide(fragment2);
        break;
    case 3:
        if (v.getId() != R.id.btn3)
            ft.hide(fragment3);
        break;
    case 4:
        if (v.getId() != R.id.btn4)
            ft.hide(fragment4);
        break;
    case 5:
        if (v.getId() != R.id.btn5)
            ft.hide(fragment5);
        break;
    }

    // show only what is needed and when it is needed
    switch (v.getId()) {
    case R.id.btn1:
        if (mCurrentTab != 1) {
            mCurrentTab = 1;
            ft.show(fragment1);
        }
        break;
    case R.id.btn2:
        if (mCurrentTab != 2) {
            mCurrentTab = 2;
            ft.show(fragment2);
        }
        break;
    case R.id.btn3:
        if (mCurrentTab != 3) {
            mCurrentTab = 3;
            ft.show(mFavoritesFragment3);
        }
        break;
    case R.id.btn4:
        if (mCurrentTab != 4) {
            mCurrentTab = 4;
            ft.show(fragment4);
        }
        break;
    case R.id.btn5:
        if (mCurrentTab != 5) {
            mCurrentTab = 5;
            ft.show(fragment5);
        }
        break;
    }

    ft.commit();
}

2 个答案:

答案 0 :(得分:0)

我不是百分百肯定,但这些问题通常是由您的活动中传递的savedInstanceState引起的:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

当你这样做时,你也传递了碎片,这些碎片可能与你实现碎片的方式不太一致(你没有显示任何代码,所以实在无法分辨)。您可以尝试简单地使用super.onCreate(null);,但每次都从头开始创建所有内容。

或者你应该正确地记住片段的状态并在初始化时设置它。

答案 1 :(得分:0)

您确定将始终调用onRestoreInstanceState吗?我不确定是否是这种情况,例如:

Why onRestoreInstanceState() never gets called

我使用的方法是这里描述的方法(参见添加导航标签部分):

http://developer.android.com/guide/topics/ui/actionbar.html