Android中添加Fragment的正確姿勢

前言:

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章