前言:
我們在平時開發中必定會運用到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就好啦!