Android Jetpack Compose 中的Tabs(TabLayout)
添加依赖
我们需要依赖于2个 accompanist
组件,你可以从下面链接中获取最新版本https://github.com/google/accompanist/tree/main/pager#pager-composable-for-jetpack-compose
def accompanist_version = "0.28.0"
implementation "com.google.accompanist:accompanist-pager:$accompanist_version" // Pager
implementation "com.google.accompanist:accompanist-pager-indicators:$accompanist_version" // Pager Indicators
准备
在实现Tabs之前,我们将创建data类和Screen类。
data class TabRowItem(
val title: String,
val icon: ImageVector,
val screen: @Composable () -> Unit,
)
这个数据类可以根据要求更改。您可以删除title
或icon
,但其中至少一个必须保留。
@Composable
fun TabScreen(
text: String,
) {
Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
Text(
text = text,
style = MaterialTheme.typography.body1,
)
}
}
这将用于我们的示例。您可以并应该稍后更改它。
最后,让我们创建选项卡列表。
val tabRowItems = listOf(
TabRowItem(
title = "Tab 1",
screen = { TabScreen(text = "Tab 1") },
icon = Icons.Rounded.Place,
),
TabRowItem(
title = "Tab 2",
screen = { TabScreen(text = "Tab 2") },
icon = Icons.Rounded.Search,
),
TabRowItem(
title = "Tab 3",
screen = { TabScreen(text = "Tab 3") },
icon = Icons.Rounded.Star,
)
)
实现
val pagerState = rememberPagerState()
val coroutineScope = rememberCoroutineScope()
pagerState
将需要记住和保持页面器的状态。
coroutineScope
将用于pagerState
滚动。
Column(
modifier = Modifier
.padding(contentPadding)
) {
TabRow(
selectedTabIndex = pagerState.currentPage,
indicator = { tabPositions ->
TabRowDefaults.Indicator(
Modifier.pagerTabIndicatorOffset(pagerState, tabPositions),
color = MaterialTheme.colors.secondary
)
},
) {
// Will be added later
}
}
我们首先添加TabRow
,这将是Tab的容器。
selectedTabIndex
是当前选定选项卡的索引。
indicator
表示当前选定的选项卡。
Column(
modifier = Modifier
.padding(contentPadding)
) {
TabRow(
//..
) {
tabRowItems.forEachIndexed { index, item ->
Tab(
selected = pagerState.currentPage == index,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(index) } },
icon = {
Icon(imageVector = item.icon, contentDescription = "")
},
text = {
Text(
text = item.title,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
)
}
)
}
}
在TabRow
里,我们将创建Tab
。由于我们已经创建了tabs列表,因此我们将简单地调用tabRowItems.forEachIndex
并设置Tabs
。
选择selected
属性,即此选项卡是否被选中。
icon
和text
是可选的。您可以选择其中一个或两者,就像我们的示例一样。
在onClick
方法中,我们启动coroutineScope
并调用animateScrollToPage
函数。它简单地将给定页面动画滚动到视图的中心。
Column(
modifier = Modifier
.padding(contentPadding)
) {
TabRow(
//...
) {
//...
}
HorizontalPager(
count = tabRowItems.size,
state = pagerState,
) {
tabRowItems[pagerState.currentPage].screen()
}
}
HorizontalPager
是一种水平滚动布局,允许用户在左右两侧之间翻转项目。
最后,我们将添加HorizontalPager
。count
是页面数量,state
是用于控制或观察分页器状态的对象,我们已经在上面创建了它。
在HorizontalPager
中,我们将获取当前页面并调用Screen
,这也是我们在自定义数据类中已经创建的。
完整代码如下:
val pagerState = rememberPagerState()
val coroutineScope = rememberCoroutineScope()
Column(
modifier = Modifier
.padding(contentPadding)
) {
TabRow(
selectedTabIndex = pagerState.currentPage,
indicator = { tabPositions ->
TabRowDefaults.Indicator(
Modifier.pagerTabIndicatorOffset(pagerState, tabPositions),
color = MaterialTheme.colors.secondary
)
},
) {
tabRowItems.forEachIndexed { index, item ->
Tab(
selected = pagerState.currentPage == index,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(index) } },
icon = {
Icon(imageVector = item.icon, contentDescription = "")
},
text = {
Text(
text = item.title,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
)
}
)
}
}
HorizontalPager(
count = tabRowItems.size,
state = pagerState,
) {
tabRowItems[pagerState.currentPage].screen()
}
}
效果动画如下:
源码地址
https://johncodeos.com/how-to-create-tabs-with-jetpack-compose/