Android中自定义Tab的实现

本文介绍了如何在Android中自定义Tab,通过分析TabHost和TabWidget,利用TabSpec的setIndicator方法设置自定义View。文章详细讲解了如何修改布局文件tab_custom_indicator.xml以改变Tab的外观,并创建选择器来实现切换时的背景变化。最后,提到了编码部分的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看了网上的的一些资料和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;
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值