片段管理器是否在方向更改后还原屏幕上的最后一个调度片段?

时间:2017-08-17 17:28:46

标签: android android-fragments

该应用包含一项活动(仅包含FrameLayout)和三项Fragments(所有这些活动在结构上相同,都有一个按钮,但唯一的区别是不同的背景颜色)。

首次创建活动时,通过替换将所有片段逐个放入FrameLayout。当我们点击屏幕上的(片段的)按钮时,它会用另一个片段替换当前片段。

问题在于屏幕旋转时,活动显示应用程序首次启动时显示的片段,而不管旋转前显示的片段。

为什么会这样?为什么屏幕上没有恢复最后显示的片段?

我知道我可以使用onSavedInstanceState,但更重要的是,我想了解FragmentManager的工作原理。

主要活动:

public class MainActivity extends AppCompatActivity implements ActivityInstance {

    fraga a;
    fragb b;
    fragc c;
    FragmentManager fm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fm = getSupportFragmentManager();


        if (fm.findFragmentByTag("a")!=null){
            a  = (fraga) fm.findFragmentByTag("a");
        }
        else {
            a = new fraga();
            FragmentTransaction ft = fm.beginTransaction();
            ft.add(R.id.frame, a, "a" );
            ft.commit();
        }

        if (fm.findFragmentByTag("b")!=null){
            b  = (fragb) fm.findFragmentByTag("b");
        }
        else {
            b = new fragb();
            FragmentTransaction fx = fm.beginTransaction();
            fx.add(R.id.frame, b, "b" );
            fx.commit();
        }

        if (fm.findFragmentByTag("c")!=null){
            c  = (fragc) fm.findFragmentByTag("c");
        }
        else {
            c = new fragc();
            FragmentTransaction fl = fm.beginTransaction();
            fl.add(R.id.frame, c, "c" );
            fl.commit();
        }

    }

    public void changefrag(int i) { //This method is called by the fragment 
                                     using the ActivityInstance interface
        switch (i){
            case 1: FragmentTransaction f1 = fm.beginTransaction().replace(R.id.frame, a, "a" );
                    f1.commit();
                    break;
            case 2: FragmentTransaction f2 = fm.beginTransaction().replace(R.id.frame, b, "b" );
                    f2.commit();
                    break;
            case 3: FragmentTransaction f3 = fm.beginTransaction().replace(R.id.frame, c, "c" );
                    f3.commit();
                    break;
            default:
                    {Toast.makeText(this, "default", Toast.LENGTH_SHORT).show();}
        }
    }
}

1 个答案:

答案 0 :(得分:4)

FragmentManager会在方向更改后恢复上次显示的fragment。看起来您在fragment的每个方向更改后添加了新的Activity。因此,在最后一个片段上添加了一个新片段,它覆盖了最后一个片段。

仅当fragment为空时,才应在onCreate中添加savedInstanceStatesavedInstanceState仅在第一次为null时,在方向更改后不会为null。

if (savedInstanceState == null) {
    // add your fragment
} 
// else -  don't add fragment, because all the fragments are restored automatically