You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jetpack Compose创建WhatsApp式自适应宽度可滚动标签页?

Jetpack Compose 实现自适应宽度可滚动标签页(类似WhatsApp样式)

你要实现的这种宽度随文本自适应、支持横向滚动的标签页,在Jetpack Compose中可以通过ScrollableTabRow配合自定义Tab内容来实现,不需要额外第三方组件。

核心实现思路

  1. 用ScrollableTabRow作为基础容器,它天生支持横向滚动,解决标签过多时的溢出问题
  2. 自定义Tab布局,取消默认的强制填充宽度行为,让Tab宽度由内部文本内容决定
  3. 通过状态管理选中标签的索引,同步更新标签样式和对应页面内容

完整代码示例

import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Group
import androidx.compose.material.icons.filled.Inbox
import androidx.compose.material.icons.filled.MarkEmailUnread
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRowDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp

// 定义标签数据结构
data class TabItem(
    val title: String,
    val icon: ImageVector
)

@Composable
fun WhatsAppStyleTabScreen() {
    val tabItems = listOf(
        TabItem("全部", Icons.Default.Inbox),
        TabItem("未读", Icons.Default.MarkEmailUnread),
        TabItem("群组", Icons.Default.Group)
    )

    var selectedTabIndex by remember { mutableIntStateOf(0) }
    val scrollState = rememberScrollState()

    Column(modifier = Modifier.fillMaxSize()) {
        // 可滚动自适应宽度标签栏
        ScrollableTabRow(
            selectedTabIndex = selectedTabIndex,
            modifier = Modifier.horizontalScroll(scrollState),
            edgePadding = 8.dp,
            indicator = { tabPositions ->
                // 让指示器宽度匹配选中标签的实际宽度
                TabRowDefaults.PrimaryIndicator(
                    modifier = Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]),
                    height = 2.dp
                )
            }
        ) {
            tabItems.forEachIndexed { index, item ->
                // 自定义自适应宽度Tab
                Tab(
                    selected = selectedTabIndex == index,
                    onClick = { selectedTabIndex = index },
                    modifier = Modifier.padding(horizontal = 4.dp)
                ) {
                    Column(
                        modifier = Modifier.padding(vertical = 12.dp),
                        horizontalAlignment = Alignment.CenterHorizontally,
                        verticalArrangement = Arrangement.Center
                    ) {
                        Text(
                            text = item.title,
                            style = MaterialTheme.typography.labelMedium,
                            color = if (selectedTabIndex == index) {
                                MaterialTheme.colorScheme.primary
                            } else {
                                MaterialTheme.colorScheme.onSurfaceVariant
                            }
                        )
                    }
                }
            }
        }

        // 标签对应的内容区域
        Box(
            modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Text(
                text = "${tabItems[selectedTabIndex].title} 页面内容",
                style = MaterialTheme.typography.headlineSmall
            )
        }
    }
}

关键细节说明

  • ScrollableTabRow:替代默认TabRow,提供横向滚动能力,edgePadding控制标签与屏幕边缘的间距
  • 自定义Tab:通过Modifier.padding(horizontal = 4.dp)给标签添加左右间距,内部用Column包裹内容,让Tab宽度自适应文本
  • 指示器:使用tabIndicatorOffset让指示器宽度匹配选中标签的实际宽度,和WhatsApp样式一致
  • 状态管理:用mutableIntStateOf保存选中索引,实现标签切换时的样式和内容同步

内容的提问来源于stack exchange,提问作者jess her

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 19:18:18