Android开发之ViewPager+Fragment+FragmentTabHost实现底部菜单

在Android开发中,底部菜单是经常要使用的,如微信、微博、支付宝等,实现底部菜单有好几种方式,大致分为:
  • 通过TabWidget实现
  • 隐藏TabWidget,通过RadioGroup和RadioButton实现底部菜单栏
  • 通过FragmentTabHost实现
  • 通过5.0以后的TabLayout实现
  • 通过最近推出的 Bottom navigation

本文的主题是 ViewPager+Fragment+FragmentTabHost 实现底部菜单
1、构造4个Fragment,每个布局类似如下
<?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" 
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="fragment1" 
        android:textSize="20dp"/>

</LinearLayout>
复制代码
2、Activity布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

     <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/black" >
    </android.support.v4.app.FragmentTabHost>

</LinearLayout>
复制代码

上面是一个ViewPager,用于装载Fragment进行滑动;下面放一个FragmentTabHost,用于存放底部菜单的具体内容,它的颜色就是黑色的,菜单的文字为白色,这样好区分。

3、底部菜单布局,一般都是图片在上,文字在下,美工一般都会把图片提前准备好
<?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:gravity="center"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/tab_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tab_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/white" />

</LinearLayout>
复制代码
4、Activity代码
//注意是继承 FragmentActivity
public class MainActivity extends FragmentActivity
{

	// FragmentTabHost
	private FragmentTabHost mTabHost;
	// layoutInflater
	private LayoutInflater layoutInflater;
	// imageViewArray数组,用于显示底部菜单
	private int imageViewArray[] = { R.drawable.mywork, R.drawable.mypatient,
			R.drawable.infusion, R.drawable.personal };
	// textViewArray数组
	private String textViewArray[] = { "工作", "回家", "互动", "我的" };
	// Fragment数组
	private List<Fragment> list = new ArrayList<Fragment>();
	// ViewPager
	private ViewPager vp;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_tab_layout);

		initView();
	}

	/**
	 * 控件初始化
	 */
	private void initView()
	{
		vp = (ViewPager) findViewById(R.id.pager);

		layoutInflater = LayoutInflater.from(this);
		mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
		mTabHost.setup(this, getSupportFragmentManager(), R.id.pager);

		Fragment1 fragment1 = new Fragment1();
		Fragment2 fragment2 = new Fragment2();
		Fragment3 fragment3 = new Fragment3();
		Fragment4 fragment4 = new Fragment4();
		list.add(fragment1);
		list.add(fragment2);
		list.add(fragment3);
		list.add(fragment4);

		int count = textViewArray.length;

		// 添加菜单内容
		for (int i = 0; i < count; i++)
		{
			// 一个菜单就是一个TabSpec,然后添加到FragmentTabHost中
			TabSpec tabSpec = mTabHost.newTabSpec(textViewArray[i])
					.setIndicator(getTabItemView(i));
			mTabHost.addTab(tabSpec, list.get(i).getClass(), null);
			// 默认让第一个选中
			mTabHost.getTabWidget().getChildAt(0)
					.setBackgroundResource(R.drawable.selector_tab_background);
		}

		// ViewPager添加Adapter,这里用FragmentPagerAdapter
		vp.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager())
		{

			@Override
			public int getCount()
			{

				return list.size();
			}

			@Override
			public android.support.v4.app.Fragment getItem(int arg0)
			{
				return list.get(arg0);
			}
		});

	}

	private View getTabItemView(int i)
	{
		View view = layoutInflater.inflate(R.layout.tab_content, null);
		ImageView mImageView = (ImageView) view
				.findViewById(R.id.tab_imageview);
		TextView mTextView = (TextView) view.findViewById(R.id.tab_textview);
		mImageView.setBackgroundResource(imageViewArray[i]);
		mTextView.setText(textViewArray[i]);
		return view;
	}

}
复制代码

上面的 selector_tab_background.xml文件如下,只是改变了一下背景色来示意选中

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_selected="true" android:drawable="@color/purple"/>
    <item android:state_focused="true" android:drawable="@color/purple"/>
    <item android:state_pressed="true" android:drawable="@color/purple"/>
    <item android:drawable="@android:color/black"/>

</selector>
复制代码

这样写了以后,只能实现底部有菜单,上面能滑动,但是底部菜单和上面的ViewPager并没有关联起来,怎么关联呢?首先,上面滑动的时候,需要监听滑动到哪里了,然后下面的菜单跟着联动;同理,如果点击了下面的菜单,上面的ViewPager应该滑动到对应的Fragment

5、关联ViewPager与底部菜单
  • ViewPager实现OnPageChangeListener监听器,目的是让ViewPager滑动的时候能够带着底部菜单联动
	vp.setOnPageChangeListener(new OnPageChangeListener()
		{

			@Override
			public void onPageScrollStateChanged(int arg0)
			{

			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2)
			{

			}

			@Override
			public void onPageSelected(int arg0)
			{
				// 选中菜单
				mTabHost.setCurrentTab(arg0);
				// 设置对应菜单高亮
				mTabHost.getTabWidget()
						.getChildAt(arg0)
						.setBackgroundResource(
								R.drawable.selector_tab_background);
			}
		});
复制代码
  • FragmentTabHost实现setOnTabChangedListener,目的是当点击了下面的菜单时,上面的ViewPager应该滑动到对应的Fragment
mTabHost.setOnTabChangedListener(new OnTabChangeListener()
		{

			@Override
			public void onTabChanged(String tabId)
			{
				// 获取点击的菜单的位置
				int position = mTabHost.getCurrentTab();
				// ViewPager滑动到对应的位置
				vp.setCurrentItem(position);
			}
		});
复制代码

至此,这个双向关联的底部菜单就已经完成了。如果要求内容不需要滑动,如微信、支付宝那种,只有底部点击切换Fragment的功能,那么只需要将Activity布局中的ViewPager换成一个FrameLayout占位,然后在程序替换Fragment即可~~

转载于:https://juejin.im/post/5a31137ef265da432b4ad1c9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值