加载的Fragment的方法有:、
1、replace():替换,当前Fragment不再使用时使用。
2、add():添加,如果有Fragment会覆盖它。
Fragment的应用场景大部分是想qq、微信那样。那么MainActivity里加载Fragment应该是复用的,如果用replace()加载,每次都会创建新的Fragment,显然不是我们想要的结果。方案:用add()、hide()和show()三个方法结合完成,主要代码如下。
步骤一:封装显示Fragment的方法
public void showFragment(int index) {
FragmentTransaction ft = fragmentManager.beginTransaction();
hideFragment(ft);
//注意这里设置位置
position = index;
switch (index) {
case FRAGMENT_ONE:
/**
* 如果Fragment为空,就新建一个实例
* 如果不为空,就将它从栈中显示出来
*/
if (needFragment == null) {
needFragment = new NeedFragment();
ft.add(R.id.fl_fragment, needFragment);
} else {
ft.show(needFragment);
}
break;
case FRAGMENT_TWO:
if (serviceFragment == null) {
serviceFragment = new ServiceFragment();
ft.add(R.id.fl_fragment, serviceFragment);
} else {
ft.show(serviceFragment);
}
break;
}
ft.commitAllowingStateLoss();
}
加载之前先hide。 public void hideFragment(FragmentTransaction ft) {
//如果不为空,就先隐藏起来
if (needFragment != null) {
ft.hide(needFragment);
}
if (serviceFragment != null) {
ft.hide(serviceFragment);
}
}
步骤二:直接调用showFragment()
fragmentManager = getSupportFragmentManager();
showFragment(FRAGMENT_ONE);
当屏幕旋转时,Fragment会重叠,因为屏幕旋转时activity走了onCreate方法,调用了showFragement方法,在原先的基础上重新调用了add()方法。
旋转时activity的生命周期onSaveInstanceState->onStop->onDestroy->onCreate->onStart->onRestoreInstanceState->onResume,重新获得焦点,进行交互。
解决思路 1:旋转时保存当前fragment的信息,旋转后重新加载该fragment。2:设置fragment为static,因为在每次显示的时候都会隐藏一次fragment,如果不设置static属性,旋转时fragment因为activity的destroy,fragment也会销毁。fragment为null时,不能隐藏,但是这样可能会出现内存泄露的情况,所以我们不用这种方法。使用第一种靠谱。
主要代码实现(第一种方法的代码)
/**
* 解决屏幕旋转时:重复添加fragment。
* @param outState
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
//屏幕旋转时记录位置
outState.putInt(POSITION, position);
Log.e("tag","onSaveInstanceState");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.e("tag","onRestoreInstanceState");
//屏幕恢复时取出位置
showFragment(savedInstanceState.getInt(POSITION));
super.onRestoreInstanceState(savedInstanceState);
}