優化多個Fragment切換出現的問題FragmentTabAdapter
阿新 • • 發佈:2019-01-12
我們在開發過程中經常會用到多個Fragment之間進行切換,剛開始是有一些開發者可能會用到這種單例方法:
if (mFragment != null) {
ft.hide(mFragment);
}
這種方法避免了多次多fragment進行例項化,例項化一次多次使用的優化方法,但是用這個話,經過我們測試的工作者的暴力測試就會出現問題,比如:多個fragment亂串的問題,因為這個用做的話fragment的生命週期可能會亂掉,所以這樣的寫法並不是做好的我最近研究了下網上的一些大神發現有一個更好的實現,而且生命週期穩定,書寫方便,下面就是說下這個adapter:
這個介面卡可以節省我們挺多程式碼的,我們在FragmentActivity中可以這樣寫:public class FragmentTabAdapter implements RadioGroup.OnCheckedChangeListener { private List<Fragment> fragments; // 一個tab頁面對應一個Fragment private RadioGroup rgs; // 用於切換tab private FragmentActivity fragmentActivity; // Fragment所屬的Activity private int fragmentContentId; // Activity中所要被替換的區域的id private int currentTab; // 當前Tab頁面索引 private OnRgsExtraCheckedChangedListener onRgsExtraCheckedChangedListener; // 用於讓呼叫者在切換tab時候增加新的功能 public FragmentTabAdapter(FragmentActivity fragmentActivity, List<Fragment> fragments, int fragmentContentId, RadioGroup rgs) { this.fragments = fragments; this.rgs = rgs; this.fragmentActivity = fragmentActivity; this.fragmentContentId = fragmentContentId; // 預設顯示第一頁 FragmentTransaction ft = fragmentActivity.getSupportFragmentManager() .beginTransaction(); ft.add(fragmentContentId, fragments.get(0)); ft.commit(); rgs.setOnCheckedChangeListener(this); } @Override public void onCheckedChanged(RadioGroup radioGroup, int checkedId) { for (int i = 0; i < rgs.getChildCount(); i++) { if (rgs.getChildAt(i).getId() == checkedId) { // 如果設定了切換tab額外功能功能介面 if (null != onRgsExtraCheckedChangedListener) { onRgsExtraCheckedChangedListener.OnRgsExtraCheckedChanged( radioGroup, checkedId, i); } Fragment fragment = fragments.get(i); FragmentTransaction ft = obtainFragmentTransaction(i); getCurrentFragment().onPause(); // 暫停當前tab // getCurrentFragment().onStop(); // 暫停當前tab if (fragment.isAdded()) { // fragment.onStart(); // 啟動目標tab的onStart() fragment.onResume(); // 啟動目標tab的onResume() } else { ft.add(fragmentContentId, fragment); } showTab(i); // 顯示目標tab ft.commit(); } } } /** * 切換tab * * @param idx */ public void showTab(int idx) { for (int i = 0; i < fragments.size(); i++) { Fragment fragment = fragments.get(i); FragmentTransaction ft = obtainFragmentTransaction(idx); if (idx == i) { ft.show(fragment); } else { ft.hide(fragment); } ft.commit(); } currentTab = idx; // 更新目標tab為當前tab } /** * 獲取一個帶動畫的FragmentTransaction * * @param index * @return */ private FragmentTransaction obtainFragmentTransaction(int index) { FragmentTransaction ft = fragmentActivity.getSupportFragmentManager() .beginTransaction(); // 設定切換動畫 // if (index > currentTab) { // ft.setCustomAnimations(R.anim.slide_right_in, // R.anim.slide_left_out); // } else { // ft.setCustomAnimations(R.anim.slide_left_in, R.anim.slide_right_out); // // } return ft; } public int getCurrentTab() { return currentTab; } public Fragment getCurrentFragment() { return fragments.get(currentTab); } public OnRgsExtraCheckedChangedListener getOnRgsExtraCheckedChangedListener() { return onRgsExtraCheckedChangedListener; } public void setOnRgsExtraCheckedChangedListener( OnRgsExtraCheckedChangedListener onRgsExtraCheckedChangedListener) { this.onRgsExtraCheckedChangedListener = onRgsExtraCheckedChangedListener; } /** * 切換tab額外功能功能介面 */ public static class OnRgsExtraCheckedChangedListener { public void OnRgsExtraCheckedChanged(RadioGroup radioGroup, int checkedId, int index) { } } }
首先新建一個集合用於存放fragment:
public List<Fragment> fragments = new ArrayList<Fragment>();
在這個裡面的按鈕都是用的RadioGroup和RadioButton:
雖然這裡的RadioButton的ID沒有用但是還是要寫的,不然的話介面卡分不清你到底點選了哪一個:
然後就是下面的這個:
TabOrderFragment,
TabStatisticsFragment
TabDishFragment
TabMoreFragment
這是四個fragment放到集合中
R.id.tab_content是你要替換的佈局的ID
mTabsRg是RadioGroup的物件;
這樣就可以了不用做其他什麼操作了呢
</pre><pre>
fragments.add(new TabOrderFragment()); fragments.add(new TabStatisticsFragment()); fragments.add(new TabDishFragment()); fragments.add(new TabMoreFragment()); mTabAdapter = new FragmentTabAdapter(this, fragments, R.id.tab_content, mTabsRg);