Material 在 Jetpack Compose 中使用列而不是 LazyColumn 滑动以关闭
Material Swipe To Dismiss in Jetpack Compose with a Column instead of a LazyColumn
在我的 Jetpack Compose 项目中,我想使用 Material SwipeToDismiss 通过滑动来删除项目。在我的可组合项中,我在列表中使用列而不是 LazyColumn。问题是当项目被删除时,重组开始并且所有后续项目也被删除(因为 dismissState 似乎与下一个项目相同)。例如,如果该列有 7 个项目,我删除了项目 #5,那么项目 #6 和项目 #7 也被删除了。
如果我使用具有固定高度的 LazyColumn(可能是因为按键),它会起作用,但我只想要一个没有滚动或固定高度的项目列表。有什么建议如何得到这个 运行?
@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun DocumentationsList(
modifier: Modifier = Modifier,
task: DBTask,
documentations: List<DBDocumentation>,
onDocumentationDelete: (DBDocumentation) -> Unit,
) {
Column(
modifier = modifier
) {
for ((index, documentation) in documentations.withIndex()) {
var dismissState = rememberDismissState(initialValue = DismissValue.Default)
if (dismissState.isDismissed(DismissDirection.EndToStart)) {
onDocumentationDelete(documentation)
}
SwipeToDismiss(
state = dismissState,
modifier = Modifier.padding(vertical = 4.dp),
directions = setOf(DismissDirection.EndToStart),
dismissThresholds = { direction ->
FractionalThreshold(if (direction == DismissDirection.StartToEnd) 0.25f else 0.5f)
},
background = {
val direction = dismissState.dismissDirection ?: return@SwipeToDismiss
val color by animateColorAsState(
when (dismissState.targetValue) {
DismissValue.Default -> Color.LightGray
DismissValue.DismissedToEnd -> Color.Green
DismissValue.DismissedToStart -> Color.Red
}
)
val alignment = when (direction) {
DismissDirection.StartToEnd -> Alignment.CenterStart
DismissDirection.EndToStart -> Alignment.CenterEnd
}
val icon = when (direction) {
DismissDirection.StartToEnd -> Icons.Default.Done
DismissDirection.EndToStart -> Icons.Default.Delete
}
val scale by animateFloatAsState(
if (dismissState.targetValue == DismissValue.Default) 0.75f else 1f
)
Box(
Modifier.fillMaxSize().background(color).padding(horizontal = 20.dp),
contentAlignment = alignment
) {
Icon(
icon,
contentDescription = "Localized description",
modifier = Modifier.scale(scale)
)
}
},
dismissContent = {
Card(
elevation = animateDpAsState(
if (dismissState.dismissDirection != null) 4.dp else 0.dp
).value
) {
// Layout here
}
}
)
}
}
您可以使用 key
,它的工作原理与 LazyColumn
key
参数相同:
Column(
modifier = modifier
) {
for ((index, documentation) in documentations.withIndex()) {
key(uniqueKey) {
// your view
}
}
}
这不应该是您的 index
,因为它会在删除后针对已删除项目下面的所有项目发生变化,它应该是您 collection 中每个项目的唯一标识符。
在我的 Jetpack Compose 项目中,我想使用 Material SwipeToDismiss 通过滑动来删除项目。在我的可组合项中,我在列表中使用列而不是 LazyColumn。问题是当项目被删除时,重组开始并且所有后续项目也被删除(因为 dismissState 似乎与下一个项目相同)。例如,如果该列有 7 个项目,我删除了项目 #5,那么项目 #6 和项目 #7 也被删除了。
如果我使用具有固定高度的 LazyColumn(可能是因为按键),它会起作用,但我只想要一个没有滚动或固定高度的项目列表。有什么建议如何得到这个 运行?
@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun DocumentationsList(
modifier: Modifier = Modifier,
task: DBTask,
documentations: List<DBDocumentation>,
onDocumentationDelete: (DBDocumentation) -> Unit,
) {
Column(
modifier = modifier
) {
for ((index, documentation) in documentations.withIndex()) {
var dismissState = rememberDismissState(initialValue = DismissValue.Default)
if (dismissState.isDismissed(DismissDirection.EndToStart)) {
onDocumentationDelete(documentation)
}
SwipeToDismiss(
state = dismissState,
modifier = Modifier.padding(vertical = 4.dp),
directions = setOf(DismissDirection.EndToStart),
dismissThresholds = { direction ->
FractionalThreshold(if (direction == DismissDirection.StartToEnd) 0.25f else 0.5f)
},
background = {
val direction = dismissState.dismissDirection ?: return@SwipeToDismiss
val color by animateColorAsState(
when (dismissState.targetValue) {
DismissValue.Default -> Color.LightGray
DismissValue.DismissedToEnd -> Color.Green
DismissValue.DismissedToStart -> Color.Red
}
)
val alignment = when (direction) {
DismissDirection.StartToEnd -> Alignment.CenterStart
DismissDirection.EndToStart -> Alignment.CenterEnd
}
val icon = when (direction) {
DismissDirection.StartToEnd -> Icons.Default.Done
DismissDirection.EndToStart -> Icons.Default.Delete
}
val scale by animateFloatAsState(
if (dismissState.targetValue == DismissValue.Default) 0.75f else 1f
)
Box(
Modifier.fillMaxSize().background(color).padding(horizontal = 20.dp),
contentAlignment = alignment
) {
Icon(
icon,
contentDescription = "Localized description",
modifier = Modifier.scale(scale)
)
}
},
dismissContent = {
Card(
elevation = animateDpAsState(
if (dismissState.dismissDirection != null) 4.dp else 0.dp
).value
) {
// Layout here
}
}
)
}
}
您可以使用 key
,它的工作原理与 LazyColumn
key
参数相同:
Column(
modifier = modifier
) {
for ((index, documentation) in documentations.withIndex()) {
key(uniqueKey) {
// your view
}
}
}
这不应该是您的 index
,因为它会在删除后针对已删除项目下面的所有项目发生变化,它应该是您 collection 中每个项目的唯一标识符。