前言:
我们在平时开发中必定会运用到Fragment,经常会出现一些莫名其妙的问题,比如在旋转屏幕或被系统杀掉重启时,出现bug,这说明你添加Fragment的姿势不对!在这里我总结一下自己在项目中添加Fragment的方式,我且称之为正确姿势,如有不对的地方或者更好的方式,欢迎大家留言指出!
正文:
一、在一个Activity中添加一个Fragment的正确姿势
Activity中代码(直接拿去套用):
//用户ID的KEY
public static final String KEY_UID = "KEY_UID";
private HomeFragment HomeFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_acts);
addDetailFragment(savedInstanceState);
}
private void addDetailFragment(Bundle savedInstanceState) {
//添加Fragment应以这种方式,当旋转屏幕和被系统杀掉重启时,才不会出问题
if (savedInstanceState == null) {
FragmentManager fm = getSupportFragmentManager(); //获取Fragment管理器对象
FragmentTransaction ft = fm.beginTransaction(); //开启事务
if (fm.findFragmentById(R.id.fragment_container) == null) {
HomeFragment = new HomeFragment();
} else {
HomeFragment = (HomeFragment) fm.findFragmentById(R.id.videos_fragment_container);
ft.remove(HomeFragment);
fm.popBackStack();
ft.commit();
ft = fm.beginTransaction();
}
//传入一些参数
Bundle bundle = new Bundle();
bundle.putLong(KEY_UID, mUserId);
......
HomeFragment.setArguments(bundle);
ft.add(R.id.videos_fragment_container, HomeFragment); //将fragment添加到布局当中
ft.commit(); //千万别忘记提交事务
}
}
Activity的layout中:
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
二、在一个Activity中添加几个Fragment的正确姿势
现在的好多App进入主页后都会有首页、发现和我的三个页面,下面我就以此为例。还是看Activity中的代码:
//定义代表各个界面的常量
public static final int HOME_POS = 0; //首页
public static final int DISCOVERY_POS = 1; //发现
public static final int MINE_POS = 2; //我的
private HomeFragment mHomeFragment; //首页Fragment
private DiscoveryFragment mDiscoveryFragment; //发现Fragment
private UserInfoFragment mMineFragment; //我的Fragment
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//状态变化时删除老的Fragment
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Fragment fragment = fm.findFragmentById(R.id.frag_container);
if (fragment != null) {
ft.remove(fragment);
fm.popBackStack();
ft.commit();
}
}
setSelection(HOME_POS); //默认选择首页
我们继续看setSelection()方法干了什么:
public void setSelection(int position) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
hideAllFragments(transaction); //先隐藏全部Fragment
//然后是各个Fragment的创建和显示
switch (position) {
case HOME_POS:
if (mHomeFragment == null) {
mHomeFragment = new HomeFragment();
transaction.add(R.id.frag_container, mHomeFragment);
} else {
transaction.show(mHomeFragment);
}
mHomeTab.setSelected(true);
break;
case DISCOVERY_POS:
if (mDiscoveryFragment == null) {
mDiscoveryFragment = new DiscoveryFragment();
transaction.add(R.id.frag_container, mDiscoveryFragment);
} else {
transaction.show(mDiscoveryFragment);
}
mDiscoveryTab.setSelected(true);
break;
case MINE_POS:
if (mMineFragment == null) {
mMineFragment = new UserInfoFragment();
transaction.add(R.id.frag_container, mMineFragment);
} else {
transaction.show(mMineFragment);
}
mMineTab.setSelected(true);
break;
}
transaction.commit(); //千万别忘记提交事务
}
在显示某个Fragment之前,我将全部Fragment隐藏,这样可以确定不会显示出错,再看看hideAllFragments():
private void hideAllFragments(FragmentTransaction transaction) {
if (mHomeFragment != null) transaction.hide(mHomeFragment);
if (mDiscoveryFragment != null) transaction.hide(mDiscoveryFragment);
if (mMineFragment != null) transaction.hide(mMineFragment);
}
Activity的layout代码:
<FrameLayout
android:id="@+id/frag_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
OK,之后再遇到添加Fragment的问题,直接copy就好啦!