该应用包含一项活动(仅包含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();}
}
}
}
答案 0 :(得分:4)
FragmentManager
会在方向更改后恢复上次显示的fragment
。看起来您在fragment
的每个方向更改后添加了新的Activity
。因此,在最后一个片段上添加了一个新片段,它覆盖了最后一个片段。
仅当fragment
为空时,才应在onCreate
中添加savedInstanceState
。 savedInstanceState
仅在第一次为null时,在方向更改后不会为null。
if (savedInstanceState == null) {
// add your fragment
}
// else - don't add fragment, because all the fragments are restored automatically