Android 底部导航栏(TabHost + TabWidget)实现方案

TabHost + TabWidget 是 Android 早期的官方底部导航方案

一、核心概念

1. 三个必须有的组件

  • TabHost:整个标签页的总控制器
  • TabWidget:底部 / 顶部的标签按钮栏
  • FrameLayout(tabcontent):每个标签对应的内容区域

2. 三个系统固定 ID(不能改)

复制代码
@android:id/tabhost       → TabHost
@android:id/tabs          → TabWidget
@android:id/tabcontent    → 内容容器

二、完整布局写法

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<TabHost
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 1. 系统必须的内容容器 -->
    <FrameLayout
        android:id="@android:id/tabcontent"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- 这里可以放各个 tab 对应的布局 -->
    </FrameLayout>

    <!-- 2. 底部 Tab 栏 -->
    <TabWidget
        android:id="@android:id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom">  <!-- 放在底部 -->
    </TabWidget>

</TabHost>

三、Java 代码完整使用步骤

1. Activity 必须继承 TabActivity

java 复制代码
public class MainActivity extends TabActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 1. 获取 TabHost
        TabHost tabHost = getTabHost();

        // 2. 创建 Tab1
        TabHost.TabSpec tab1 = tabHost.newTabSpec("tab1");
        tab1.setIndicator("首页");      // 标签文字
        tab1.setContent(R.id.tab1);     // 对应布局ID

        // 3. 创建 Tab2
        TabHost.TabSpec tab2 = tabHost.newTabSpec("tab2");
        tab2.setIndicator("我的");
        tab2.setContent(R.id.tab2);

        // 4. 添加到 TabHost
        tabHost.addTab(tab1);
        tabHost.addTab(tab2);

        // 5. 默认选中第一个
        tabHost.setCurrentTab(0);
    }
}

2. 每个 Tab 对应内容布局示例

在 @android:id/tabcontent 里放:

xml 复制代码
<LinearLayout
    android:id="@+id/tab1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">
    <TextView
        android:text="首页内容"
        android:textSize="24sp"/>
</LinearLayout>

<LinearLayout
    android:id="@+id/tab2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">
    <TextView
        android:text="我的页面"
        android:textSize="24sp"/>
</LinearLayout>

四、监听 Tab 切换事件

java 复制代码
tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
    @Override
    public void onTabChanged(String tabId) {
        if (tabId.equals("tab1")) {
            // 切换到首页
        } else if (tabId.equals("tab2")) {
            // 切换到我的
        }
    }
});

五、重点注意事项

  1. 三个 ID 必须严格使用系统 ID
  2. Activity 必须继承 TabActivity,如果不继承 TabActivity,TabHost 必须先 setup () 再用。
java 复制代码
TabHost tabHost = findViewById(R.id.tabhost);
tabHost.setup();
  1. TabWidget 默认在顶部,想放底部要加

    android:layout_gravity="bottom"

  2. 每个 TabSpec 的 tag 必须唯一,重复会导致切换错乱。

    newTabSpec("tab1")
    newTabSpec("tab2")

六、现代替代方案

Google 现在推荐:
BottomNavigationView (底部导航)
TabLayout + ViewPager2(可滑动顶部标签)

相关推荐
三少爷的鞋3 小时前
Android 架构七条铁律:架构师真正设计的不是代码,而是秩序
android
xiangxiongfly9155 小时前
Android GsonFactory总结
android·gson·gsonfactory
WythePlus6 小时前
Android 14 SELinux策略深度解析
android·安全策略·selinux策略
俩个逗号。。10 小时前
Kotlin flow 详解
android·开发语言·kotlin
橙光成长12 小时前
android-ad-cleaner:android免 Root 批量关闭系统开屏与营销推送
android·1024程序员节
深圳雨林凯AI12 小时前
图案裂变的底色衰减:alpha通道、亮度对比与白墨分色的量化拆解
android
mmsx12 小时前
Android 模块化收口:能力组合框架、手写 LifecycleOwner 与热修复共存
android
恋猫de小郭15 小时前
Flutter 可以更直接地调用原生 API 了,Dart Direct Native Interop
android·前端·flutter
2501_9160088915 小时前
iPhone 设备信息查看,用 KeyMob 看型号、序列号、电池健康和 UDID
android·ios·小程序·https·uni-app·iphone·webview
好的佩奇1 天前
蓝牙之通信架构
android·flutter·蓝牙