您的位置:首页 > 移动开发 > Android开发

三种方式实现Android页面底部导航栏

2014-12-12 20:50 465 查看
我们在Android手机上使用新浪微博和QQ等一些软件时,经常会遇到类似下面这种页面底部导航栏的控件,使用这种导航栏可以在手机屏幕的一页中显示尽可能多的内容,如下图所示:



下面我将实现这种导航栏的三种方法总结如下:

一、使用TabHost实现(TabHost在新版的Android SDK中已经不推荐使用了,但是这里还是可以了解下它的用法)

使用TabHost的Activity需要继承自TabActivity,且布局文件中的id有三个地方需要固定,布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    <span style="color:#ff0000;">android:id="@android:id/tabhost"</span>
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <FrameLayout
            <span style="color:#ff0000;">android:id="@android:id/tabcontent"</span>
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

        <TabWidget
            <span style="color:#ff0000;">android:id="@android:id/tabs"</span>
            android:background="@drawable/tab_bg"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</TabHost>
注意上面的布局文件中标红的三个地方,这三个地方的id值必须写成这样,然后是Activity中的代码:

package cn.yubo.testtabhost;

import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TabHost;
import android.widget.TabWidget;

public class TabHostActivity extends TabActivity {
	private TabHost tabHost;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_tab_host);
		
		tabHost = getTabHost();
		//添加三个Tab标签
		tabHost.addTab(tabHost.newTabSpec("tab1")
				.setIndicator("选项1", getResources().getDrawable(R.drawable.tab_activity_normal))
				.setContent(new Intent(this, TabHost1Activity.class)));
		tabHost.addTab(tabHost.newTabSpec("tab2")
				.setIndicator("选项2", getResources().getDrawable(R.drawable.tab_activity_normal))
				.setContent(new Intent(this, TabHost2Activity.class)));
		tabHost.addTab(tabHost.newTabSpec("tab3")
				.setIndicator("选项3", getResources().getDrawable(R.drawable.tab_img_selector))
				.setContent(new Intent(this, TabHost3Activity.class)));
	}
}
在上面的代码中,我们首先通过getTabHost()方法得到一个TabHost对象,然后添加了三个导航栏标签,通过setContent()方法指定了每个标签跳转到的页面,最后的效果图为:



这里不知道为什么在底部的Tab中没有显示出图标来,明明通过setIndicator方法设置了图标,但是没显示出来。

下面说下第二种实现导航栏的方法:

二、使用ViewPager+RadioGroup实现

这种方法实现起来比较容易,就是在页面上加个ViewPager,底部放一个RadioGroup,里面放几个RadioButton起到互斥作用,请看代码,首先是布局文件:

<?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.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <RadioGroup
        android:id="@+id/radiogroup"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/tab_bg"
        android:gravity="center_vertical"
        android:orientation="horizontal" >

        <RadioButton
            android:id="@+id/tab1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:checked="true"
            android:drawableTop="@drawable/tab_img_selector"
            android:gravity="center"
            android:paddingLeft="0dp"
            android:text="选项1" />

        <RadioButton
            android:id="@+id/tab2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:drawableTop="@drawable/tab_img_selector"
            android:gravity="center"
            android:paddingLeft="0dp"
            android:text="选项2" />

        <RadioButton
            android:id="@+id/tab3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:drawableTop="@drawable/tab_img_selector"
            android:gravity="center"
            android:paddingLeft="0dp"
            android:text="选项2" />
    </RadioGroup>

</LinearLayout>
在上面的代码中需要注意的一个地方是,在RadioButton里,我们设置了button属性为@null,这样就去掉了原来的RadioButton中的圆圈,但是如果不加paddingLeft="0dp"这个属性的话,你会发现RadioButton中的图标和文字还是靠右的,就是说,虽然button属性设置了@null,但是button占据的位置还是在的,只有设置了paddingLeft="0dp"和gravity="center"属性后,RadioButton中的图标和文字才会居中。

写完了布局文件的代码,再来看看Activity中的代码该怎么写:

package cn.yubo.testtabhost;

import java.util.ArrayList;
import java.util.List;

import net.tsz.afinal.FinalActivity;
import net.tsz.afinal.annotation.view.ViewInject;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TextView;

/**
 * 使用ViewPager和RadioGroup实现底部导航栏
 * 
 * @author yubo<br/>
 *         2014年12月12日
 */
public class ViewPagerTabActivity extends FinalActivity {
	@ViewInject(id = R.id.viewpager)
	private ViewPager viewPager;
	@ViewInject(id = R.id.radiogroup)
	private RadioGroup radioGroup;
	@ViewInject(id = R.id.tab1)
	private RadioButton tab1;
	@ViewInject(id = R.id.tab2)
	private RadioButton tab2;
	@ViewInject(id = R.id.tab3)
	private RadioButton tab3;

	private List<View> viewList;

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

		initViewPager();
		radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			public void onCheckedChanged(RadioGroup group, int checkedId) {
				switch (checkedId) {
				case R.id.tab1:
					viewPager.setCurrentItem(0);
					break;
				case R.id.tab2:
					viewPager.setCurrentItem(1);
					break;
				case R.id.tab3:
					viewPager.setCurrentItem(2);
					break;
				}
			}
		});
	}

	private void initViewPager() {
		viewList = new ArrayList<View>();
		viewList.add(LayoutInflater.from(this).inflate(R.layout.page_layout,
				null));
		viewList.add(LayoutInflater.from(this).inflate(R.layout.page_layout,
				null));
		viewList.add(LayoutInflater.from(this).inflate(R.layout.page_layout,
				null));
		viewPager.setAdapter(new MyViewPagerAdapter());
		viewPager.setOnPageChangeListener(new OnPageChangeListener() {

			public void onPageSelected(int arg0) {
				switch (arg0) {
				case 0:
					tab1.setChecked(true);
					tab2.setChecked(false);
					tab3.setChecked(false);
					break;
				case 1:
					tab1.setChecked(false);
					tab2.setChecked(true);
					tab3.setChecked(false);
					break;
				case 2:
					tab1.setChecked(false);
					tab2.setChecked(false);
					tab3.setChecked(true);
					break;
				}
			}

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

			public void onPageScrollStateChanged(int arg0) {
			}
		});
	}

	private class MyViewPagerAdapter extends PagerAdapter {

		@Override
		public int getCount() {
			return viewList.size();
		}

		@Override
		public boolean isViewFromObject(View arg0, Object arg1) {
			return arg0 == arg1;
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			container.removeView(viewList.get(position));
		}

		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			View view = viewList.get(position);
			container.addView(view);
			TextView textView = (TextView) view
					.findViewById(R.id.page_textview);
			textView.setText("第" + position + "页的数据");
			return view;
		}

	}
}
这里也没什么难点的,就是设置ViewPager滑动时切换RadioButton的选中状态,然后设置RadioButton被选中时显示ViewPager的哪个页面,上面的代码中用到了AFinal框架,使用FinalActivity中的注解方式获取控件,其他就没什么了,效果图如下:



三、使用Fragment+RadioButton实现导航栏

这种方式也蛮不错的,最后实现的效果图跟第二种方法的一样,区别之处就在于,第二种方法使用了ViewPager,所以上面的区域是可以左右滑动的,而我们这第三种方式实现的导航栏,上面一部分的区域是不可以左右滑动的,页面的切换只能通过下面的导航栏tab来进行,布局文件就不上了,跟第二种方法的布局文件一致,关键是Activity中的代码:

package cn.yubo.testtabhost;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;

public class MyFragmentActivity extends FragmentActivity {
	private FragmentManager manager;
	private FragmentTransaction tran;
	private RadioGroup radioGroup;

	@Override
	protected void onCreate(Bundle arg0) {
		super.onCreate(arg0);
		setContentView(R.layout.activity_my_fragment);
		manager = getSupportFragmentManager();
		tran = manager.beginTransaction();
		tran.replace(R.id.content, new Fragment1());
		tran.commit();
		
		radioGroup = (RadioGroup) findViewById(R.id.radiogroup);
		radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				tran = manager.beginTransaction();
				switch(checkedId){
				case R.id.tab1:
					tran.replace(R.id.content, new Fragment1());
					break;
				case R.id.tab2:
					tran.replace(R.id.content, new Fragment2());
					break;
				case R.id.tab3:
					tran.replace(R.id.content, new Fragment3());
					break;
				}
				tran.commit();
			}
		});
	}
}
使用Fragment做这种页面的切换时,我们要继承FragmentActivity类,其中比较重要的地方是FragmentManager和FragmentTransaction,通过这两个类才能实现页面的切换,下面放上源码:

下载源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: