Android Fragment嵌套ViewPager,ViewPager嵌套多个Fragment

前几天,项目中要实现这么一个功能。就配置了下。其实很简单,首先 需要阅读下我转载的前两篇文章,都是转载的郭神的,写的非常好。我的项目中逢者必用,其实就相当于一个很好的框架来使用,非常方便。

前两篇的项目地址Android Fragment应用实战,使用碎片向ActivityGroup说再见和Android ActionBar应用实战,高仿微信主界面的设计,认真阅读,你会感觉到受益颇深。(当然,如果你不是大神)

其实和前两篇都重复了,都不想粘贴代码了,为了便于学习,还是粘贴上吧。

首先,写了一个BaseActivity,便于封装一些方法继承

public class BaseActivity extends FragmentActivity {
	protected Context mContext;

	@Override
	protected void onCreate(Bundle arg0) {
		// TODO Auto-generated method stub
		super.onCreate(arg0);
		ActionBar actionBar = getActionBar();
		actionBar.hide();//隐藏标题栏
		mContext = this;
	}

	protected void Toasters(String message) {
		Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
	}

}
首先,应用启动后会进入MainActivity,此Activity会加载三个Fragment,随便定义三个(首页,消息,我的)

效果图如下:

Android Fragment嵌套ViewPager,ViewPager嵌套多个Fragment_第1张图片

首页,消息,我的,三个fragment大同小异,布局在fragment类中加载出来就行,这里就不粘贴代码了。

最终要的是MainActivity,加载了三个fragment,点击效果,显示效果。其实是首次点击的时候首次加载了fragment,后来点击就隐藏了其他的fragment,显示了当前的fragment,这里需要处理隐藏其他的fragment,避免了多个fragment显示到界面上。

public class MainActivity extends BaseActivity implements OnClickListener {

	/**
	 * 首页
	 **/
	private LinearLayout main_linear_home;
	private ImageView main_imageview_home;
	private TextView main_txtview_home;
	/**
	 * 消息
	 **/
	private LinearLayout main_linear_msg;
	private ImageView main_imageview_msg;
	private TextView main_txtview_msg;
	/**
	 * 我的
	 **/
	private LinearLayout main_linear_user;
	private ImageView main_imageview_user;
	private TextView main_txtview_user;

	/**
	 * 用于对Fragment进行管理
	 */
	private FragmentManager fragmentManager;
	/**
	 * 选中的颜色值
	 */
	private int main_txtColor_sel = 0;
	/**
	 * 正常颜色值
	 */
	private int main_txtColor_nol = 0;
	/**
	 * FrameLayout
	 */
	private FrameLayout main_new_frame;

	private HomeFragment homeFragment;
	private MessageFragment messageFragment;
	private MyFragment myFragment;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		setOnClickEvent();
		// 初始化API
	}

	/**
	 * @Description: TODO 初始化布局控件
	 * @author Sunday
	 * @date 2016年3月26日
	 */
	private void initView() {
		// TODO Auto-generated method stub

		main_new_frame = (FrameLayout) findViewById(R.id.main_new_frame);
		// 布局
		main_linear_home = (LinearLayout) findViewById(R.id.main_linear_home);
		main_linear_msg = (LinearLayout) findViewById(R.id.main_linear_msg);
		main_linear_user = (LinearLayout) findViewById(R.id.main_linear_my);
		// 底部图片
		main_imageview_home = (ImageView) findViewById(R.id.main_imageview_home);
		main_imageview_msg = (ImageView) findViewById(R.id.main_imageview_msg);
		main_imageview_user = (ImageView) findViewById(R.id.main_imageview_my);
		// 底部文字
		main_txtview_home = (TextView) findViewById(R.id.main_txtview_home);
		main_txtview_msg = (TextView) findViewById(R.id.main_txtview_msg);
		main_txtview_user = (TextView) findViewById(R.id.main_txtview_my);

		fragmentManager = getSupportFragmentManager();
		main_txtColor_nol = getBaseContext().getResources().getColor(R.color.main_txt_nor);
		main_txtColor_sel = getBaseContext().getResources().getColor(R.color.main_txt_sel);

		setTabSelection(0);
	}

	private void setOnClickEvent() {
		main_linear_home.setOnClickListener(this);
		main_linear_msg.setOnClickListener(this);
		main_linear_user.setOnClickListener(this);
	}

	/*
	 *
	 */
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub

		switch (v.getId()) {
		case R.id.main_linear_home:
			setTabSelection(0);
			break;
		case R.id.main_linear_msg:
			setTabSelection(1);
			break;
		case R.id.main_linear_my:
			setTabSelection(2);
			break;
		default:
			break;
		}
	}

	/**
	 * 
	 * @Description: TODO 底部切换选择fragment
	 * @author Sunday
	 * @date 2016年3月26日
	 */
	public void setTabSelection(int index) {
		// 底部切换
		clearSelection(index);
		// 开启一个Fragment事务
		FragmentTransaction transaction = fragmentManager.beginTransaction();
		// 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况
		hideFragments(transaction);
		switch (index) {

		case 0:
			if (homeFragment == null) {
				homeFragment = new HomeFragment();
				transaction.add(R.id.main_new_frame, homeFragment);

			} else {
				transaction.show(homeFragment);
			}
			break;

		case 1:
			if (messageFragment == null) {
				messageFragment = new MessageFragment();
				transaction.add(R.id.main_new_frame, messageFragment);

			} else {
				transaction.show(messageFragment);
			}
			break;

		case 2:
			if (myFragment == null) {
				myFragment = new MyFragment();
				transaction.add(R.id.main_new_frame, myFragment);

			} else {
				transaction.show(myFragment);
			}
			break;
		}
		transaction.commit();
	}

	/**
	 * 
	 * @Description: TODO 清除选中状态
	 * @author Sunday
	 * @date 2016年3月26日
	 */
	private void clearSelection(int index) {
		main_imageview_home.setImageResource(R.drawable.shouye_normal);
		main_txtview_home.setTextColor(main_txtColor_nol);
		main_imageview_msg.setImageResource(R.drawable.massage_normal);
		main_txtview_msg.setTextColor(main_txtColor_nol);
		main_imageview_user.setImageResource(R.drawable.my_normal);
		main_txtview_user.setTextColor(main_txtColor_nol);

		if (index == 0) {
			main_imageview_home.setImageResource(R.drawable.shouye_pressed);
			main_txtview_home.setTextColor(main_txtColor_sel);
		}

		if (index == 1) {
			main_imageview_msg.setImageResource(R.drawable.massage_pressed);
			main_txtview_msg.setTextColor(main_txtColor_sel);
		}

		if (index == 2) {
			main_imageview_user.setImageResource(R.drawable.my_pressed);
			main_txtview_user.setTextColor(main_txtColor_sel);
		}
	}

	/**
	 * 
	 * @Description: TODO 隐藏所有的fragment,防止多个fragment显示在界面
	 * @author Sunday
	 * @date 2016年3月26日
	 */
	private void hideFragments(FragmentTransaction transaction) {
		if (homeFragment != null) {
			transaction.hide(homeFragment);
		}
		if (messageFragment != null) {
			transaction.hide(messageFragment);
		}
		if (myFragment != null) {
			transaction.hide(myFragment);
		}
	}

	// 定义一个变量,来标识是否退出
	private static boolean isExit = false;

	Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			isExit = false;
		}
	};

	/**
	 * 处理返回键事件
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			exit();
			return false;
		}
		return super.onKeyDown(keyCode, event);
	}

	private void exit() {
		if (!isExit) {
			isExit = true;
			Toasters("再按一次退出应用");
			// 利用handler延迟发送更改状态信息
			mHandler.sendEmptyMessageDelayed(0, 2000);
		} else {
			finish();
			System.exit(0);
		}
	}
}
其实就这么简单的实现了框架的搭建,开发中其实很多项目都是采用了这种框架。

现在,我们再来研究下,让首页加载ViewPager,ViewPager嵌套了三个fragment,fragment可以点击切换,也可以滑动切换。

tab滑动的效果,我们任然是使用的第三方的开源框架PagerSlidingTabStrip,稳定性非常好,还可以随意修改源码。

首先需要将PagerSlidingTabStrip的源码下载下来,并集成到我们的项目当中,PagerSlidingTabStrip的GitHub主页地址是:https://github.com/astuetz/PagerSlidingTabStrip 。

最重要的HomeFragment的代码如下:

public class HomeFragment extends Fragment {

	/**
	 * PagerSlidingTabStrip的实例
	 */
	private PagerSlidingTabStrip tabs;

	/**
	 * 获取当前屏幕的密度
	 */
	private DisplayMetrics dm;

	private OneFragment oneFragment;
	private TwoFragment twoFragment;
	private ThreeFragment threeFragment;
	/* 
	 *
	 */

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View view = inflater.inflate(R.layout.fragment_home, null);
		setOverflowShowingAlways();
		dm = getResources().getDisplayMetrics();
		ViewPager pager = (ViewPager)view. findViewById(R.id.pager);
		pager.setOffscreenPageLimit(0);//设置ViewPager的缓存界面数,默认缓存为2
		tabs = (PagerSlidingTabStrip) view.findViewById(R.id.tabs);
		pager.setAdapter(new MyPagerAdapter(getChildFragmentManager()));
		tabs.setViewPager(pager);
		setTabsValue();
		return view;
	}

	/**
	 * 对PagerSlidingTabStrip的各项属性进行赋值。
	 */
	private void setTabsValue() {
		// 设置Tab是自动填充满屏幕的
		tabs.setShouldExpand(true);
		// 设置Tab的分割线是透明的
		tabs.setDividerColor(Color.TRANSPARENT);
		// 设置Tab底部线的高度
		tabs.setUnderlineHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, dm));
		// 设置Tab Indicator的高度
		tabs.setIndicatorHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, dm));
		// 设置Tab标题文字的大小
		tabs.setTextSize((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, dm));
		// 设置Tab Indicator的颜色
		tabs.setIndicatorColor(Color.parseColor("#d83737"));//#d83737   #d83737(绿)
		// 设置选中Tab文字的颜色 (这是我自定义的一个方法)
		tabs.setSelectedTextColor(Color.parseColor("#ffffff"));
		// 取消点击Tab时的背景色
		tabs.setTabBackground(0);
	}

	public class MyPagerAdapter extends FragmentPagerAdapter {

		public MyPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		private final String[] titles = { "TAB1", "TAB2", "TAB3" };

		@Override
		public CharSequence getPageTitle(int position) {
			return titles[position];
		}

		@Override
		public int getCount() {
			return titles.length;
		}

		@Override
		public Fragment getItem(int position) {
			switch (position) {
			case 0:
				if (oneFragment == null) {
					oneFragment = new OneFragment();
				}
				return oneFragment;
			case 1:
				if (twoFragment == null) {
					twoFragment = new TwoFragment();
				}
				return twoFragment;
			case 2:
				if (threeFragment == null) {
					threeFragment = new ThreeFragment();
				}
				return threeFragment;
			default:
				return null;
			}
		}

	}
	
	private void setOverflowShowingAlways() {
		try {
			ViewConfiguration config = ViewConfiguration.get(getParentFragment().getActivity());
			Field menuKeyField = ViewConfiguration.class
					.getDeclaredField("sHasPermanentMenuKey");
			menuKeyField.setAccessible(true);
			menuKeyField.setBoolean(config, false);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

其次,布局文件也拿上来了

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

   <com.sunday.slidetabfragment.view.PagerSlidingTabStrip
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:background="@color/light_black_bg" />

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

最终的效果图如下:

Android Fragment嵌套ViewPager,ViewPager嵌套多个Fragment_第2张图片

效果就如期待的那样,是不是觉得超级简单。如果要是觉得难看,tab样式和颜色当然是可以修改的,图片也可以使用UI设计的。

源码地址,点击下载

你可能感兴趣的:(android,viewpager,Fragment,Fragment多层嵌套)