我有一个屏幕,用户可以在其中看到他们从不同类别保存的推荐,并在 FlowRow 的帮助下实现上面的过滤器按钮:
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun SavedScreen(
savedRecommendationsMap: Map<Pair<CATEGORY, Boolean>, List<Recommendation>?>,
onClick: (Recommendation, CATEGORY) -> Unit,
onFilterButtonClick: (category: CATEGORY, isSelected: Boolean) -> Unit,
modifier: Modifier = Modifier,
) {
Rebugger(
trackMap = mapOf(
"savedRecommendationsMap" to savedRecommendationsMap,
"onClick" to onClick,
"onFilterButtonClick" to onFilterButtonClick,
"modifier" to modifier,
),
)
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(dimensionResource(R.dimen.padding_medium))
.fillMaxSize(),
) {
FlowRow(
horizontalArrangement = Arrangement.Start,
verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.padding_small)),
modifier = Modifier.fillMaxWidth(),
) {
savedRecommendationsMap.forEach() { (key, value) ->
Log.d(
"SavedScreen",
"Category: ${key.first}, isSelected: ${key.second}, recommendations: ${value?.size ?: 0}"
)
FilterButton(
onFilterButtonClick = onFilterButtonClick,
filterName = key.first,
isFilterSelected = key.second,
modifier = Modifier.padding(end = dimensionResource(R.dimen.padding_small)),
)
}
}
HorizontalDivider(
thickness = 2.dp,
modifier = Modifier.padding(vertical = dimensionResource(R.dimen.padding_medium)),
)
if (!savedRecommendationsMap.any { it.value != null }) {
NothingScreen(modifier = modifier)
} else {
LazyColumn(
modifier = Modifier
.fillMaxSize(),
) {
item {
savedRecommendationsMap.forEach { (key, value) ->
if (key.second == true) {
value?.forEach {
SavedScreenCard(
recommendation = it,
onClick = onClick,
category = key.first,
)
}
}
}
}
}
}
}
}
左侧是预览。它工作正常,但在设备上(右)时,您可以看到只出现 2 个按钮。此外,当我试图找到解决方案时,我遇到了另一个问题,即该可组合项被重新组合了四次。我使用Rebugger并使用logged来查找原因,但我仍然无法修复它。
日志:
Category: COFFEESHOPS, isSelected: true, recommendations: 0
Category: RESTRAUNTS, isSelected: true, recommendations: 0
Category: PARKS, isSelected: true, recommendations: 0
Category: SHOPPINGCENTERS, isSelected: true, recommendations: 0
Category: HOTELS, isSelected: true, recommendations: 0
🐞Rebugger recomposed because
`onClick` changed from `Function2<com.example.prguetravel.model.Recommendation, com.example.prguetravel.utils.CATEGORY, kotlin.Unit>` to `Function2<com.example.prguetravel.model.Recommendation, com.example.prguetravel.utils.CATEGORY, kotlin.Unit>`,
`onFilterButtonClick` changed from `Function2<com.example.prguetravel.utils.CATEGORY, java.lang.Boolean, kotlin.Unit>` to `Function2<com.example.prguetravel.utils.CATEGORY, java.lang.Boolean, kotlin.Unit>`,
`modifier` instance changed, but content remains the same -> `androidx.compose.foundation.layout.PaddingValuesElement@e5200000`
Category: COFFEESHOPS, isSelected: true, recommendations: 0
Category: RESTRAUNTS, isSelected: true, recommendations: 0
Category: PARKS, isSelected: true, recommendations: 0
Category: SHOPPINGCENTERS, isSelected: true, recommendations: 0
Category: HOTELS, isSelected: true, recommendations: 0
🐞 Rebugger activated on `Rebugger`
Category: COFFEESHOPS, isSelected: true, recommendations: 0
Category: RESTRAUNTS, isSelected: true, recommendations: 0
Category: PARKS, isSelected: true, recommendations: 0
Category: SHOPPINGCENTERS, isSelected: true, recommendations: 0
Category: HOTELS, isSelected: true, recommendations: 0
🐞Rebugger recomposed because
`onClick` changed from `Function2<com.example.prguetravel.model.Recommendation, com.example.prguetravel.utils.CATEGORY, kotlin.Unit>` to `Function2<com.example.prguetravel.model.Recommendation, com.example.prguetravel.utils.CATEGORY, kotlin.Unit>`,
`onFilterButtonClick` changed from `Function2<com.example.prguetravel.utils.CATEGORY, java.lang.Boolean, kotlin.Unit>` to `Function2<com.example.prguetravel.utils.CATEGORY, java.lang.Boolean, kotlin.Unit>`,
`modifier` instance changed, but content remains the same -> `androidx.compose.foundation.layout.PaddingValuesElement@e5200000`
Category: COFFEESHOPS, isSelected: true, recommendations: 0
Category: RESTRAUNTS, isSelected: true, recommendations: 0
Category: PARKS, isSelected: true, recommendations: 0
Category: SHOPPINGCENTERS, isSelected: true, recommendations: 0
Category: HOTELS, isSelected: true, recommendations: 0
Category: COFFEESHOPS, isSelected: true, recommendations: 0
Category: RESTRAUNTS, isSelected: true, recommendations: 0
Category: PARKS, isSelected: true, recommendations: 0
Category: SHOPPINGCENTERS, isSelected: true, recommendations: 0
Category: HOTELS, isSelected: true, recommendations: 0
FlowRow
似乎不完整,因为 SavedScreen
可组合项隐藏在 TopAppBar 后面。您可能在某些时候使用过 Scaffold
。确保您将脚手架提供的填充应用到 content
:
Scaffold(
topBar = {
//...
},
content = { innerPadding ->
Box(
modifier = Modifier.padding(innerPadding)
) {
//...
}
}
)
在我们研究任何重组分析之前:
您正在使用
item
迭代地将新元素添加到单个 LazyColumn forEach
。这将使 LazyColumn 本身毫无意义,因为它始终只包含一个项目。
我不知道您到底想要实现什么,但如果您想将每个
SavedScreenCard
显示为 LazyColumn 中的单个项目,请考虑按如下方式更新您的代码:
LazyColumn(
modifier = Modifier.fillMaxSize(),
) {
savedRecommendationsMap.forEach { (key, value) ->
if (key.second == true) {
value?.forEach { recommendation ->
item {
SavedScreenCard(
recommendation = recommendation,
onClick = onClick,
category = key.first,
)
}
}
}
}
}
这将导致正确的 LazyColumn 使用,其中仅组合当前可见的项目(以及其他一些项目),而其他项目在滚动时延迟组合。