我想要一个类似TikTok的个人资料界面效果。
顶部是ProfilPicture
和username
,下方是一个带有TabRow
(Posts
、Drafts
、Likes
、Favorites
)的stickyHeader
,再下方是一个带有4个屏幕(Posts
、Drafts
、Likes
、Favorites
)的HorizontalPager
,每个屏幕都包含一个列表。
如果我在Compose中构建这个,会崩溃,因为我不能把两个LazyColumns
嵌套在一起。
以下是我尝试实现的简短版本:
val tabList = listOf("Posts", "Drafts", "Likes", "Favorites")
val pagerState: PagerState = rememberPagerState(initialPage = 0)
val coroutineScope = rememberCoroutineScope()
LazyColumn(modifier = Modifier.fillMaxSize()) {
item {
Box(
modifier = Modifier
.fillMaxWidth()
.height(50.dp),
contentAlignment = Alignment.Center
) {
//Profile Header (Picture, Username, Followers, etc)
Text(text = "Profile Picture")
}
}
stickyHeader {
TabRow(
modifier = Modifier.fillMaxWidth(),
backgroundColor = Color.Black,
contentColor = Color.White,
selectedTabIndex = pagerState.currentPage,
indicator = { tabPositions ->
TabRowDefaults.Indicator(
Modifier.pagerTabIndicatorOffset(pagerState, tabPositions)
)
}
) {
// Add tabs for all of our pages
tabList.forEachIndexed { index, title ->
Tab(
text = { Text(title) },
selected = pagerState.currentPage == index,
onClick = {
coroutineScope.launch {
pagerState.animateScrollToPage(index)
}
},
)
}
}
}
item {
HorizontalPager(
state = pagerState,
count = tabList.size
) { page: Int ->
when (page) {
0 -> PostsList()
1 -> DraftsList()
2 -> LikesList()
else -> FavoritesList()
}
}
}
}
例如,在PostList()
组合中有:
@Composable
fun PostList(){
LazyColumn() {
items(50){ index ->
Button(onClick = { /*TODO*/ },
modifier = Modifier.fillMaxWidth()) {
Text(text = "Button $index")
}
}
}
}
这是我遇到的崩溃:
Vertically scrollable component was measured with an infinity maximum height constraints, which is disallowed. One of the common reasons is nesting layouts like LazyColumn and Column(Modifier.verticalScroll()). If you want to add a header before the list of items please add a header as a separate item() before the main items() inside the LazyColumn scope. There are could be other reasons for this to happen: your ComposeView was added into a LinearLayout with some weight, you applied Modifier.wrapContentSize(unbounded = true) or wrote a custom layout. Please try to remove the source of infinite constraints in the hierarchy above the scrolling container.
编辑:
为 LazyColumn
子元素设置固定高度可以避免应用崩溃,但并不是很令人满意的解决方案。
当 HorizontalPager
中的 4 个列表大小不同时,会出现奇怪和有缺陷的行为,看起来也不对。
我尝试的另一件事是使用 FlowRow
替换 LazyColumn
,这似乎也可以解决崩溃,但在这里我也得到了奇怪的行为,HorizontalPager
中的列表同步滚动,这不是我想要的。
HorizontalPager
是使这个任务如此困难的原因,在没有它的情况下,这不是问题。
这是测试项目: https://github.com/DaFaack/TikTokScrollBehaviourCompose
这是当我给LazyColumn
一个固定高度2500.dp
时的外观,只有这样大的高度才能实现所需的滚动行为。
这里的缺点是即使列表为空,它也有2500的高度,这会导致糟糕的用户体验,因为它允许用户滚动,即使列表为空。