最近要实现一个选项卡的效果,类似于腾讯新闻客户端,点击屏幕下方的tab选项切换页面,效果图如下:

其实这就是一个典型的选项卡,可以通过使用TabHost组件方便的在窗口上放置多个标签页。一般在使用TabHost的时候,都需要activity继承TabActivity,然而TabActivity已经不推荐使用了,官方文档如下:
很显然,新的应用应该使用Fragments取代TabActivity,既然如此,那就用Fragments实现好了,步骤如下:
(1)新建activity_main.xml文件,其中TabWidget代表选项卡的标签条,fragment代表具体每个页面。
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@android:id/tabhost"
tools:context=".MainActivity" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="55dip"
android:layout_alignParentBottom="true"
>
</TabWidget>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@android:id/tabs"
>
<fragment
android:name="com.stefanli.bct.Tab1Fragment"
android:id="@+id/tab1"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<fragment
android:name="com.stefanli.bct.Tab2Fragment"
android:id="@+id/tab2"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<fragment
android:name="com.stefanli.bct.Tab3Fragment"
android:id="@+id/tab3"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<fragment
android:name="com.stefanli.bct.Tab4Fragment"
android:id="@+id/tab4"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
</RelativeLayout>
</TabHost>
(2)创建Fragment,其中R.layout.tab1即为该选项页面的布局文件,具体不再给出。
public class Tab1Fragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.tab1, container, false);
}
}
(3)自定义tab样式,布局文件和自定义View如下:(PS:自定义是为了更好控制tab样式,满足各种效果,系统自带的很丑而且很难调整)。
tab_menu.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="match_parent"
android:background="@color/tab_bg"
tools:context=".MainActivity" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" >
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@drawable/tab1_selected" />
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/icon"
android:layout_centerHorizontal="true"
android:layout_marginTop="3dip"
android:text="@string/tab_session"
android:textColor="@color/tab_text_nor_color"
android:textSize="12sp" />
</RelativeLayout>
</RelativeLayout>
自定义控件TabView如下:
/**
* 自定义TabHost的Tab样式
* @author Stefanli
*
*/
public class TabView extends RelativeLayout {
private ImageView mIcon;
private TextView mContent;
private Context mContext;
public TabView(Context context) {
super(context);
mContext = context;
init();
}
public TabView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init();
}
private void init(){
LayoutInflater inflater=(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.tab_menu, this);
mIcon = (ImageView)findViewById(R.id.icon);
mContent = (TextView)findViewById(R.id.content);
}
/**
* 设置图标
* @param resId
* 图标资源Id
*/
public void setIcon(int resId){
mIcon.setImageResource(resId);
}
/**
* 设置内容文本资源
* @param resId
* 内容文本资源Id
*/
public void setContentText(int resId){
mContent.setText(resId);
}
/**
* 判断是否被选中
* @param isChecked
*/
public void setIsChecked(boolean isChecked){
if(isChecked){
mContent.setTextColor(getResources().getColor(R.color.tab_text_selected_color));
}else{
mContent.setTextColor(getResources().getColor(R.color.tab_text_nor_color));
}
}
}
(4)最后一步,创建类继承FragmentActivity,通过TabHost对象创建添加选项卡。
public class MainFragment extends FragmentActivity {
private TabHost mTabHost;
private TabWidget mTabWidget;
private TabView mTabView; //自定义Tab选项卡View
private int[] mNormalIcon; //未被选中图标Id
private int[] mSelectedIcon; //被选中图标Id
private int[] mContentTextId; //文本内容Id
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mNormalIcon = new int[]{R.drawable.tab1_normal,R.drawable.tab2_normal,R.drawable.tab3_normal,R.drawable.tab4_normal};
mSelectedIcon = new int[]{R.drawable.tab1_selected,R.drawable.tab2_selected,R.drawable.tab3_selected,R.drawable.tab4_selected};
mContentTextId = new int[]{R.string.tab_news,R.string.tab_order,R.string.tab_picture,R.string.tab_movie};
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setup();
mTabWidget = mTabHost.getTabWidget();
mTabWidget.setStripEnabled(false);
mTabView = new TabView(this);
mTabHost.addTab(mTabHost.newTabSpec(getString(mContentTextId[0])).setIndicator(new TabView(this)).setContent(R.id.tab1));
mTabHost.addTab(mTabHost.newTabSpec(getString(mContentTextId[1])).setIndicator(new TabView(this)).setContent(R.id.tab2));
mTabHost.addTab(mTabHost.newTabSpec(getString(mContentTextId[2])).setIndicator(new TabView(this)).setContent(R.id.tab3));
mTabHost.addTab(mTabHost.newTabSpec(getString(mContentTextId[3])).setIndicator(new TabView(this)).setContent(R.id.tab4));
setTabStyle();
mTabHost.setOnTabChangedListener(new OnTabChangeListener() {
@Override
public void onTabChanged(String arg0) {
setTabStyle();
}
});
}
/**
* 设置tab选项卡样式
*/
private void setTabStyle(){
for (int i = 0; i < mTabWidget.getChildCount(); i++){
mTabView = (TabView)mTabWidget.getChildAt(i);
mTabView.setContentText(mContentTextId[i]);
if (mTabHost.getCurrentTab() == i){
//tab被选中状态
mTabView.setIsChecked(true);
mTabView.setIcon(mSelectedIcon[i]);
}else{
//tab未被选中状态
mTabView.setIsChecked(false);
mTabView.setIcon(mNormalIcon[i]);
}
}
}
}
最终实现效果如下:
![]()

因为代码实在太过简单,不作过多分析,一看就懂。新手上路,请多指教~