看了网上的的一些资料和android源码之后,总结出自定义Tab的大概实现,记录以备后查。
android中的tab控件显示通过TabHost和TabWidget来实现,在TabHost.TabSpec提供了tab自定义外观的实现方法:
TabSpec android.widget.TabHost.TabSpec.setIndicator(View view);
我们提供自定义的View即可,android源码中默认的view有两种:一种只有TextView,另一种包含ImageView和TextView,看看第二种的布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dip"
android:layout_height="64dip"
android:layout_weight="1"
android:layout_marginLeft="-3dip"
android:layout_marginRight="-3dip"
android:orientation="vertical"
android:background="@android:drawable/tab_indicator">
<ImageView android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="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>
源文件位于:frameworks/base/core/res/res/layout/tab_indicator.xml中
在这里我们可以增加或者修改控件,或者修改控件的样式,背景色等等。
修改后保存到自己工程的layout目录下,命名为tab_custom_indicator.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dip"
android:layout_height="64dip"
android:layout_weight="1"
android:layout_marginLeft="-3dip"
android:layout_marginRight="-3dip"
android:orientation="vertical"
android:background="@drawable/tab_custom_indicator">
<ImageView android:id="@+id/iv_tab_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
这里我只保留了ImageView,让tab只显示图片
同时在drawable中提供自定义的选择器tab_custom_indicator.xml,让系统在切换不同的tab时可以显示不同的背景:
<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>
TabActivity的layout文件为main.xml:
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
</FrameLayout>
<TabWidget android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</TabHost>
这里把TabWidget放在下面,主要是为了让tab底部显示(默认的tab是顶部显示的)
布局完成之后,下面是编码部分:
public class MainActivity extends TabActivity {
private static final String TAG = "MainActivity";
private TabWidget tabWidget;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabs = getTabHost();
tabWidget = getTabWidget();
TabHost.TabSpec spec = tabs.newTabSpec("tab0");
Intent intent = new Intent().setClass(this, FirstActivity.class);
spec.setIndicator(createIndicatorView());
spec.setContent(intent);
tabs.addTab(spec);
spec = tabs.newTabSpec("tab1");
intent = new Intent().setClass(this, SecondActivity.class);
spec.setIndicator(createIndicatorView());
spec.setContent(intent);
tabs.addTab(spec);
tabs.setCurrentTab(0);//启动时显示第一个标签页
}
private View createIndicatorView() {
View tabIndicator = (RelativeLayout)LayoutInflater.from(this).inflate(
R.layout.tab_indicator, tabWidget, false);
return tabIndicator;
}
}