我们在开发过程中经常会用到多个Fragment之间进行切换,刚开始是有一些开发者可能会用到这种单例方法:
if (mFragment != null) {
ft.hide(mFragment);
}
这种方法避免了多次多fragment进行实例化,实例化一次多次使用的优化方法,但是用这个话,经过我们测试的工作者的暴力测试就会出现问题,比如:多个fragment乱串的问题,因为这个用做的话fragment的生命周期可能会乱掉,所以这样的写法并不是做好的我最近研究了下网上的一些大神发现有一个更好的实现,而且生命周期稳定,书写方便,下面就是说下这个adapter:
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) { } } }这个适配器可以节省我们挺多代码的,我们在FragmentActivity中可以这样写:
首先新建一个集合用于存放fragment:
public List<Fragment> fragments = new ArrayList<Fragment>();
虽然这里的RadioButton的ID没有用但是还是要写的,不然的话适配器分不清你到底点击了哪一个:
然后就是下面的这个:
TabOrderFragment,<pre name="code" class="java">TabStatisticsFragment
<pre name="code" class="java"> TabDishFragment
TabMoreFragment这是四个fragment放到集合中
<pre name="code" class="java"> R.id.tab_content是你要替换的布局的ID
mTabsRg是RadioGroup的对象;这样就可以了不用做其他什么操作了呢
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);
优化多个Fragment切换出现的问题FragmentTabAdapter
原文:http://blog.csdn.net/zm_crazy/article/details/45270543