深入浅出android/ophone UI实现水平布局的Tab控件

Tab UI控件是非常常见、常用的导航UI组件,使用它能够很方便地迅速切换页面。甚为强大的android当然也少不了它,在android/ophone平台上也可以很方便地使用TabHost,TabWidget来实现你的Tab。有点遗憾的是目前系统自带的UI布局只能实现垂直方向的Tab UI, 在某些项目我们不免需要水平方向的Tab UI,如果你有这种需求你可以参考本文所介绍方法。本文所述方法参考API 源代码内部实现。
1预备知识:TabHost,TabWidget, TabSpec简介
TabHost:是整个Tab ui的布局容器实质上就是是一个扩展的FrameLayout,所有的Tab UI相关组件必须位于该布局里,必须包含的组件有:
名为TabWidget的(选项卡组件布局)和选项卡内容容器
TabWidget:选项卡组件布局容器,实质上一个线性布局LinearLayout,所有Tab选项控件都放在这里,你可以使用tabHost.addTab(TabSpec tab Spec)方法将不同的选项卡内容添加的选项卡布局容器中,或许你会有点迷糊这明明是TabSpec嘛,不要急接着看
TabSpec:是一个与选项卡相关描述文件,其内部包含了一个类型为View[更确切地说是RelativeLayout]的tabIndicator,这个tabIndicator就是选项卡对应的视图,当你在执行t abHost.addTab(TabSpec tabSpec)时,内部会有个操作将此tabIndicator添加到TabWidget中:下面是摘自API的TabHost.java中关于addTab的一段代码
public void addTab(TabSpec tabSpec) {
//...
mTabWidget.addView(tabIndicator);
mTabSpecs.add(tabSpec);
//...
}
外加一个固定ID为 android:id="@android:id/tabcontent"的FrameLayout,用于容纳Tab选项卡对应的内容
2正题:一步一步编写水平方向的Tab:
第一步:改写你的tab_indicator:直接从SDK..\platforms\android-ndata\res\layout中:拷贝tab_indicator.xml命名为tab_indicator_horizontal.xml 存放于工程中layout目录中,并修改如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="64dip"
android:layout_height="0dip"
android:layout_weight="1"
android:layout_marginTop="0dip"
android:layout_marginBottom="0dip"
android:orientation="vertical"
android:background="@drawable/tab_indicator_horizontal">

<ImageView android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
style="?android:attr/tabWidgetStyle"
/>
</RelativeLayout>

第二步:编写水平Tab选项卡显示状态背景:android:background="@drawable/tab_indicator_horizontal"
同样直接从SDK..\platforms\android-ndata\res\drawable中直接拷贝tab_indicator.xml并命名为tab_indicator_horizontal.xml 存放于工程中drawable目录中,内容如下,很简单相信你应该明白是怎么回事,这个文件不需要改动,拿来就用:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected" />
<item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected" />

<!-- Focused states -->
<item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_focus" />
<item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_focus" />

<!-- Pressed -->
<item android:state_pressed="true" android:drawable="@drawable/tab_press" />
</selector>
说明:上面的drawable/tab_unselected,drawable/tab_selected实质就是图片,android本身提供的名为9patch的可拉伸自适应填充图,因为系统本身自带的是垂直方向的图,不适合在这里使用,你需要自己修改上述图片,为了简要说明这里直接使自定义图形来适配:
第三步:使用自定义图形来适配选项卡显示状态背景:
tab_focus.xml,其他如tab_unselected你亦可参照此格式自定义,这里不再重复简述
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:startColor="#88FF88" android:endColor="#55EE55"
android:angle="0"/>
<corners android:radius="6dp" />
</shape>

第四步:编写Tab ui布局main_tab_horizontal.xml:
注意下面图片使用的的定义,请自行修改
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:background="@drawable/style_theme"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<TabHost android:id="@+id/tabHost" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_weight="1">
<!-- 水平方向的Tab -->
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<!-- Tab标签控件 注意ID的方式-->
<TabWidget android:id="@android:id/tabs"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_weight="0" />

<!-- Tab 内容控件 注意ID的方式-->
<FrameLayout android:id="@android:id/tabcontent"
android:layout_height="fill_parent" android:layout_width="0dip"
android:layout_weight="1">

<!-- 使用垂直与水平ScrollView -->
<HorizontalScrollView android:layout_width="wrap_content"
android:layout_height="fill_parent" android:fillViewport="true">
<LinearLayout android:id="@+id/id_tab_view1" android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent">

<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="center_horizontal|center_vertical"
android:src="@drawable/tree2" />
</LinearLayout>
</HorizontalScrollView>

<HorizontalScrollView android:layout_width="wrap_content"
android:layout_height="fill_parent" android:fillViewport="true">
<LinearLayout android:id="@+id/id_tab_view2" android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent">

<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="center_horizontal|center_vertical"
android:src="@drawable/building3" />
</LinearLayout>
</HorizontalScrollView>
<HorizontalScrollView android:id="@+id/id_tab_view3" android:layout_width="wrap_content"
android:layout_height="fill_parent" android:fillViewport="true">
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent">

<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="center_horizontal|center_vertical"
android:src="@drawable/building1" />
</LinearLayout>
</HorizontalScrollView>
<HorizontalScrollView android:id="@+id/id_tab_view4" android:layout_width="wrap_content"
android:layout_height="fill_parent" android:fillViewport="true">
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent">

<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="center_horizontal|center_vertical"
android:src="@drawable/building2" />
</LinearLayout>
</HorizontalScrollView>
</FrameLayout>
</LinearLayout>
</TabHost>
</LinearLayout>

第五步:编写测试代码:
public class TestActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_tab_horizontal);
parseHorizontalTab();
}

Drawable icon_tab_1, icon_tab_2, icon_tab_3, icon_tab_4;

private void parseHorizontalTab() {
// 注意下面的代码用的是android.R.id.tabhost,在布局中有2个ID参数是固定的需要使用固定的ID:

// 选项卡:TabWidget->android:id/tabs
// 选项内容:FrameLayout android:id="android:id/tabcontent"
final TabHost tabHost = (TabHost) findViewById(R.id.tabHost);
tabHost.setup();
icon_tab_1 = this.getResources().getDrawable(R.drawable.icon1);
icon_tab_2 = this.getResources().getDrawable(R.drawable.icon2);
icon_tab_3 = this.getResources().getDrawable(R.drawable.icon3);
icon_tab_4 = this.getResources().getDrawable(R.drawable.icon4);
createHorizontalTab(tabHost);
}

private void createHorizontalTab(TabHost tabHost) {
tabHost.addTab(tabHost
.newTabSpec("tab1")
.setIndicator(
createIndicatorView(this, tabHost, icon_tab_1, "tab1"))
.setContent(R.id.id_tab_view1));
tabHost.addTab(tabHost
.newTabSpec("tab2")
.setIndicator(
createIndicatorView(this, tabHost, icon_tab_2, "tab2"))
.setContent(R.id.id_tab_view2));

tabHost.addTab(tabHost
.newTabSpec("tab3")
.setIndicator(
createIndicatorView(this, tabHost, icon_tab_3, "tab3"))
.setContent(R.id.id_tab_view3));
tabHost.addTab(tabHost
.newTabSpec("tab4")
.setIndicator(
createIndicatorView(this, tabHost, icon_tab_4, "tab4"))
.setContent(R.id.id_tab_view4));

TabWidget tw = tabHost.getTabWidget();
tw.setOrientation(LinearLayout.VERTICAL);//注意在此处设置此参数 使TAB 垂直布局
}

/**
* 创建自定义的 选项卡视图
*
* @param context
* @param tabHost
* @param icon
* @return
*/
private View createIndicatorView(Context context, TabHost tabHost,
Drawable icon, String title) {

LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View tabIndicator = inflater.inflate(R.layout.tab_indicator_horizontal,
tabHost.getTabWidget(), false);

final ImageView iconView = (ImageView) tabIndicator
.findViewById(R.id.icon);
final TextView titleView = (TextView) tabIndicator
.findViewById(R.id.title);
titleView.setText(title);
iconView.setImageDrawable(icon);
return tabIndicator;
}

}

更多相关文章

  1. [置顶] Android学习之--prelink
  2. Android(安卓)Gesture 手势识别使用实例
  3. App 开发 Android(安卓)Fragments 的详细使用基础篇
  4. Android设计登陆界面
  5. android的intent使用方法
  6. 开发规范:《阿里巴巴Android开发手册》之初理解
  7. 箭头函数的基础使用
  8. NPM 和webpack 的基础使用
  9. Python list sort方法的具体使用

随机推荐

  1. android USB OTG功能实现
  2. Android(Java) ArrayList更改顺序
  3. 使用Android(安卓)Studio安装NDK并配置环
  4. android frameworks开发SystemUI之Naviga
  5. Spinner的功能和用法
  6. Android(安卓)Studio 上传SVN忽略文件
  7. Bitmap保存图片到指定路径
  8. Android(安卓)找控件的五种方式,解放你的
  9. Android开发笔记之 配置并使用Android支
  10. 自制最新版adt_bundle-windows-x86_64