优化多个Fragment切换出现的问题FragmentTabAdapter

我们在开发过程中经常会用到多个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>();

在这个里面的按钮都是用的RadioGroup和RadioButton:

虽然这里的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);
时间: 2024-10-19 15:04:09

优化多个Fragment切换出现的问题FragmentTabAdapter的相关文章

【Fragment精深系列7】Fragment切换优化

一.Fragment+RadioGroup ??在项目中需要进行Fragment的切换,一直都是用replace()方法来替换Fragment:然后总感觉切换的时候有些卡顿. 1.以前的代码: radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup radioGroup, int checkI

对Fragment切换的优化

在项目中需要进行Fragment的切换,一直都是用replace()方法来替换Fragment:然后总感觉切换的时候有些卡顿,原来的代码 /** * 切换页面,这里采用回调 * * @param f */ public void switchFragment(Fragment f) { if (f == null) return; FragmentTransaction transaction = getSupportFragmentManager() .beginTransaction();

Fragment切换的演示

首先创建主布局文件,即activity_main.xml,代码如下 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="ma

解决 viewpager fragment 切换 Fragment被销毁的问题

当我们用FragmentViewPagerAdapter和ViewPager来完成滑动切换选项卡时,效果非常不错,但是后来遇到一个问题,FragmentA切换到FragmentB,再滑到FragmentC时,FragmentA的状态数据已经不予保存了,再次滑动到FragmentB时,FragmentA的oncreateView方法会重新调用,如果有网络请求,将会是非常蛋疼,在网上找了半天,最后看到viewpager中有个这样的方法setOffscreenPageLimit,设置为2,然后再一试,

Fragment切换动画

题外话: 如何把一个 "小view" 或者 "小fragment" 覆盖到一个 "全屏view" 之上(见下图). 方法一(FrameLayout + layout_marginTop ): <FrameLayout          android:layout_width="match_parent"         android:layout_height="match_parent">

MapView 和ViewPager Fragment切换黑屏问题解决方案

在项目中使用的是高德地图,放置MapView的Fragment和其他Fragment放置一个ViewPager中切换:当从MapView的Fragment切换到其他Fragment或者从其他Fragment切换到MapView就会产生闪黑边.网上有说什么设置白色背景或者设置Activity style透明.经尝试设置Activity style透明是可以解决闪黑边问题的,但是Activity透明后会看到Launcher桌面.所以这种方式也是的. 我通过修改ViewPager的过渡方式完美解决闪黑

Fragment 切换问题

public void switchContent(Fragment fragment) { if(mContent != fragment) { mContent = fragment; mFragmentMan.beginTransaction()                .setCustomAnimations(android.R.anim.fade_in, R.anim.slide_out)   .replace(R.id.content_frame, fragment) // 替

【Android】保存Fragment切换状态

前言 一般频繁切换Fragment会导致频繁的释放和创建,如果Fragment比较臃肿体验就非常不好了,这里分享一个方法. 声明 欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com 农民伯伯: http://over140.cnblogs.com 正文 一.应用场景 1.不使用ViewPager 2.不能用replace来切换Fragment,会导致Fragment释放(调用onDestroyView) 二.实现 1.xml <LinearLayout x

让多个Fragment 切换时不重新实例化

转自:http://www.yrom.net/blog/2013/03/10/fragment-switch-not-restart/ 让多个Fragment 切换时不重新实例化 在项目中需要进行Fragment的切换,一直都是用replace()方法来替换Fragment: 1 2 3 4 5 6 7 8 9 public void switchContent(Fragment fragment) { if(mContent != fragment) { mContent = fragment